CF集萃

因为cf上一堆水题,每个单独开一篇博客感觉不太好,就直接放一起好了。

CF1096D Easy Problem

给定字符串,每个位置删除要代价。求最小代价使之不含子序列"hard"。

设f[i][f]表示前i个删到只匹配f位子序列的最小代价。转移看代码吧。

 1 #include <bits/stdc++.h>
 2 
 3 typedef long long LL;
 4 const int N = 100010;
 5 
 6 int a[N];
 7 LL f[N][5];
 8 char str[N];
 9 
10 int main() {
11     int n;
12     scanf("%d", &n);
13     scanf("%s", str + 1);
14     for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
15 
16     int tag = 0;
17     for(int i = 1; i <= n; i++) {
18         if(tag == 0 && str[i] == 'h') tag++;
19         if(tag == 1 && str[i] == 'a') tag++;
20         if(tag == 2 && str[i] == 'r') tag++;
21         if(tag == 3 && str[i] == 'd') tag++;
22     }
23     if(tag != 4) {
24         printf("0\n");
25         return 0;
26     }
27 
28     for(int i = 1; i <= n; i++) {
29         f[i][0] = f[i - 1][0] + a[i] * (str[i] == 'h');
30         f[i][1] = f[i - 1][1] + a[i] * (str[i] == 'a');
31         f[i][2] = f[i - 1][2] + a[i] * (str[i] == 'r');
32         f[i][3] = f[i - 1][3] + a[i] * (str[i] == 'd');
33         if(str[i] == 'h') f[i][1] = std::min(f[i][1], f[i - 1][0]);
34         if(str[i] == 'a') f[i][2] = std::min(f[i][2], f[i - 1][1]);
35         if(str[i] == 'r') f[i][3] = std::min(f[i][3], f[i - 1][2]);
36     }
37 
38     LL ans = std::min(std::min(f[n][0], f[n][1]), std::min(f[n][2], f[n][3]));
39 
40     printf("%lld\n", ans);
41     return 0;
42 }
AC代码

猜你喜欢

转载自www.cnblogs.com/huyufeifei/p/10618055.html
cf
今日推荐