codeforces-73C. LionAge II

传送门

一个小写字母组成的字符串和允许更改次数k,n组序偶的价值,求能获得的最大价值

定义dp[k][l][i]位更改第k次时长度为l的串末尾为i时的最大收益。分原本字符串末尾就是i和不是两种去递推。

注意初始化问题。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #define INF 0x3f3f3f3f
 6 using namespace std;
 7 typedef long long LL;
 8 
 9 const int maxn = 1e2 + 10;
10 const int maxk = 110;
11 char str[maxn];
12 int val[30][30];
13 int N, K;
14 int dp[maxk][maxn][30];
15 
16 int main() {
17     scanf("%s", str);
18     int len = strlen(str);
19     scanf("%d", &K);
20     scanf("%d", &N);
21     char c1, c2;
22     int v;
23     while (N--) {
24         getchar();
25         scanf("%c %c %d", &c1, &c2, &v);
26         val[c1 - 'a'][c2 - 'a'] = v;
27     }
28     for (int k = 0; k <= K; k++) {
29         for (int l = 0; l <= len; l++) {
30             for (int i = 0; i < 26; i++) {
31                 dp[k][l][i] = -INF;
32             }
33         }
34     }
35     for (int i = 0; i < 26; i++) dp[1][1][i] = 0;
36     dp[0][1][str[0] - 'a'] = 0;
37     for (int i = 2; i <= len; i++) {
38         int t1 = str[i - 1] - 'a', t2 = str[i - 2] - 'a';
39         dp[0][i][t1] = dp[0][i - 1][t2] + val[t2][t1];
40     }
41     for (int l = 2; l <= len; l++) {
42         for (int k = 1; k <= K; k++) {
43             for (int i = 0; i < 26; i++) {
44                 for (int j = 0; j < 26; j++) {
45                     if (str[l - 1] - 'a' == j) dp[k][l][j] = max(val[i][j] + dp[k][l - 1][i], dp[k][l][j]);
46                     if (dp[k - 1][l - 1][i] == -INF) continue;
47                     dp[k][l][j] = max(dp[k][l][j], dp[k - 1][l - 1][i] + val[i][j]);
48                 }
49             }
50         }
51     }
52     int ans = -INF;
53     for (int i = 0; i <= K; i++) {
54         for (int j = 0; j < 26; j++) {
55             ans = max(ans, dp[i][len][j]);
56         }
57 
58     }
59     printf("%d
", ans);
60     return 0;
61 }
View Code
原文地址:https://www.cnblogs.com/xFANx/p/8435727.html