因为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 }