CF1096D Easy Problem

题目传送门

题目大意

给你一个长为(n)的字符串(s)以及(a_{1 ldots n}),删去第(i)个字符的代价为(a_i),你需要删去一些字符(如果一开始就符合条件当然可以不删)使得剩下的串中不含子序列 "(hard)"(子序列不需要连续),求最小代价

思路

典型的(dp)

定义状态:

(f_{i,j})(s)字符串的前(i)个字符匹配到(hard)的第(j)个字母所花的最小代价

转移:

先看(s_i)等不等于(hard)的第(j)

如果不等于,则(f_{i,j}=f_{i-1,j})

否则,就有两种选择:一种就是不继续去掉(hard)的第(j)位,一种就是继续去掉。这两者之间取(min),就是(f_{i,j})了,所以(f_{i,j}=min(f_{i-1,j-1},f_{i-1,j}+a_i))

注意

本题卡 (long) (long) ,需注意

代码

#include<bits/stdc++.h>
using namespace std;
long long n,a[100001],f[100001][5],ans;
char s[100001],c[5]={' ','h','a','r','d'};
int main(){
    scanf("%lld",&n);
    for(int i=1;i<=n;i++) scanf(" %c",&s[i]);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    memset(f,0x7f7f7f7f,sizeof(f));
    for(int i=1;i<=4;i++) f[0][i]=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=4;j++){
            if(s[i]!=c[j]) f[i][j]=f[i-1][j];
            else f[i][j]=min(f[i-1][j-1],f[i-1][j]+a[i]);
        }
    }
    ans=min(f[n][1],min(f[n][2],min(f[n][3],f[n][4])));
    printf("%lld",ans);
    return 0;
}

不要忘记点个赞哦

完结撒花

原文地址:https://www.cnblogs.com/LZY-LZY/p/12673278.html