Codeforces Round #367 (Div. 2) C. Hard problem DP
C. Hard problem
链接:
http://codeforces.com/contest/706/problem/C
题意:
给定N个字符串对于每个字符串只能将其反转,且反转每个字符串的花费给出问将这些字符串操作后按字典序排列的最小花费。
代码:
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdio> 5 #include<cstring> 6 using namespace std; 7 8 const int maxn = 100010; 9 int c[maxn]; 10 string s[maxn]; 11 string rs[maxn]; 12 long long dp[maxn][2]; 13 14 int main() 15 { 16 int n; 17 cin >> n; 18 for (int i = 1; i <= n; i++) 19 scanf("%d", &c[i]); 20 for (int i = 1; i <= n; i++) { 21 cin >> s[i]; 22 rs[i] = s[i]; 23 reverse(rs[i].begin(), rs[i].end()); 24 } 25 s[0] = rs[0] = ""; 26 memset(dp, 0x3f, sizeof(dp)); 27 dp[0][0] = dp[0][1] = 0; 28 for (int i = 1; i <= n; i++) 29 { 30 if (s[i] >= s[i - 1]) 31 dp[i][0] = min(dp[i][0], dp[i - 1][0]); 32 if (rs[i] >= s[i - 1]) 33 dp[i][1] = min(dp[i][1], c[i] + dp[i - 1][0]); 34 if (s[i] >= rs[i - 1]) 35 dp[i][0] = min(dp[i][0], dp[i - 1][1]); 36 if (rs[i] >= rs[i - 1]) 37 dp[i][1] = min(dp[i][1], c[i] + dp[i - 1][1]); 38 } 39 long long ans = min(dp[n][0], dp[n][1]); 40 if (ans > 1e15) 41 cout << "-1" << endl; 42 else 43 cout << ans << endl; 44 return 0; 45 }