Description
Vasiliy is fond of solving different tasks. Today he found one he wasn't able to solve himself, so he asks you to help.
Vasiliy is given n strings consisting of lowercase English letters. He wants them to be sorted in lexicographical order (as in the dictionary), but he is not allowed to swap any of them. The only operation he is allowed to do is to reverse any of them (first character becomes last, second becomes one before last and so on).
To reverse the i-th string Vasiliy has to spent ci units of energy. He is interested in the minimum amount of energy he has to spent in order to have strings sorted in lexicographical order.
String A is lexicographically smaller than string B if it is shorter than B (|A| < |B|) and is its prefix, or if none of them is a prefix of the other and at the first position where they differ character in A is smaller than the character in B.
For the purpose of this problem, two equal strings nearby do not break the condition of sequence being sorted lexicographically.
Input
The first line of the input contains a single integer n (2 ≤ n ≤ 100 000) — the number of strings.
The second line contains n integers ci (0 ≤ ci ≤ 109), the i-th of them is equal to the amount of energy Vasiliy has to spent in order to reverse the i-th string.
Then follow n lines, each containing a string consisting of lowercase English letters. The total length of these strings doesn't exceed 100 000.
Output
If it is impossible to reverse some of the strings such that they will be located in lexicographical order, print -1. Otherwise, print the minimum total amount of energy Vasiliy has to spent.
題目大意
現在有 n 個由小寫字母組成的字符串。他想要讓這些字符串按字典序排列,但是他不能交換任意兩個字符串。他唯一能做的事是翻轉字符串。
翻轉第 i 個字符串需要花費 ci 的能量。他想知道將所有字符串排序最少要多少能量。
兩個相鄰的字符串可以相等,不一定要嚴格遞增。
2 ≤ n ≤ 100000,0 ≤ ci ≤ 109,字符串總長不超過100000
Solution
首先我們可以考慮前 i 個字符串,假如這些字符串已經是有序的了,那么我們關心的只有所需的能量以及第 i 個字符串是否被翻轉了,之前的每個字符串是否被翻轉對之后的字符串沒有任何影響。
所以我們可以用 fi 表示第 i 個字符串不翻轉,之前的所以字符串有序的情況下所需的最少能量,用 gi 表示第 i 個字符串翻轉,之前的所以字符串有序的情況下所需的最少能量。
之后我們只要暴力判斷一下兩個相鄰的字符串分別翻轉/不翻轉的大小關系即可。
code
代碼和題解有點不太一樣,f[i][0] 表示第 i 個位置不翻轉,之前的所以字符串有序的情況下所需的最少能量值。f[i][1] 表示第 i 個位置翻轉,之前的所以字符串有序的情況下所需的最少能量值。(即把數組 f 和數組 g 合起來惹)
#include<bits/stdc++.h> #define int long long using namespace std; const int N=1e5+5,inf=1e18; string s[N][2]; int n,c[N],f[N][2],ans; signed main(){ scanf("%lld",&n); for(int i=1;i<=n;i++) scanf("%lld",&c[i]); for(int i=1;i<=n;i++){ cin>>s[i][0],s[i][1]=s[i][0]; reverse(s[i][1].begin(),s[i][1].end()); for(int j=0;j<2;j++){ f[i][j]=inf; for(int k=0;k<2;k++) if(s[i][j]>=s[i-1][k]) f[i][j]=min(f[i][j],f[i-1][k]+j*c[i]); } } ans=min(f[n][0],f[n][1]); if(ans==inf) printf("-1\n"); else printf("%lld\n",ans); return 0; }
