Codeforces Round #367 (Div. 2) C. Hard problem (dp)
阿新 • • 發佈:2019-02-14
Note
In the second sample one has to reverse string 2 or string 3. To amount of energy required to reverse the string 3 is smaller.
In the third sample, both strings do not change after reverse and they go in the wrong order, so the answer is - 1.
In the fourth sample, both strings consists of characters 'a ' only, but in the sorted order string "aa"
should go before string "aaa", thus the answer is - 1.
題解:給你n個串,要你求:要使這n個串的字典序從小到大,要消耗的費用最小是多少。改變字典序只能通過反串來改變。
dp[i][0]表示到第i個字串,第i個字串不翻轉,能消耗的最小值。
dp[i][1]表示到第i個字串,第i個字串翻轉,能消耗的最小值。
詳細看程式碼。
AC程式碼:
#pragma comment(linker, "/STACK:102400000,102400000") //#include<bits/stdc++.h> #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<map> #include<cmath> #include<queue> #include<set> #include<stack> using namespace std; typedef long long ll; typedef unsigned long long ull; #define mst(a) memset(a, 0, sizeof(a)) #define M_P(x,y) make_pair(x,y) #define rep(i,j,k) for (int i = j; i <= k; i++) #define per(i,j,k) for (int i = j; i >= k; i--) #define lson x << 1, l, mid #define rson x << 1 | 1, mid + 1, r const int lowbit(int x) { return x&-x; } const double eps = 1e-8; const int INF = 1e9+7; const ll inf =(1LL<<62) ; const int MOD = 1e9 + 7; const ll mod = (1LL<<32); const int N = 101010; template <class T1, class T2>inline void getmax(T1 &a, T2 b) { if (b>a)a = b; } template <class T1, class T2>inline void getmin(T1 &a, T2 b) { if (b<a)a = b; } int read() { int v = 0, f = 1; char c =getchar(); while( c < 48 || 57 < c ){ if(c=='-') f = -1; c = getchar(); } while(48 <= c && c <= 57) v = v*10+c-48, c = getchar(); return v*f; } int n; ll c[N]; string s1[N]; string s2[N]; ll dp[N][2]; int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif n=read(); for (int i = 1; i <= n; i++) cin >> c[i]; for (int i = 1; i <= n; i++) cin >> s1[i]; for (int i = 1; i <= n; i++) { s2[i] = s1[i]; reverse(s2[i].begin(),s2[i].end()); } dp[1][0] = 0; dp[1][1] = c[1]; for (int i = 2; i <= n; i++) { dp[i][0] = inf; dp[i][1] = inf; if (s1[i-1] <= s1[i]) dp[i][0] = min(dp[i][0],dp[i-1][0]); if (s2[i-1] <= s1[i]) dp[i][0] = min(dp[i][0],dp[i-1][1]); if (s1[i-1] <= s2[i]) dp[i][1] = min(dp[i][1],dp[i-1][0]+c[i]); if (s2[i-1] <= s2[i]) dp[i][1] = min(dp[i][1],dp[i-1][1]+c[i]); } ll ans = min(dp[n][0],dp[n][1]); if (ans == inf) puts("-1"); else printf("%I64d\n",ans); }