题意:
给一个长为1e5的串,问至少去掉多少个字符后该串中不包含hard这个子序列。
题解:
连续两场有类似的这样的题目搞砸了,心情复杂。
这个是比较简单的版本,当时真的怎么就没想到用有限状态机来表示呢。。。还是naive,太菜了。。。
用 dp[i][j] 表示到第 i 个位置为止,使得前缀为j长度的hard的子串不出现至少需要删除多少个字符。状态转移很简单,当为char==h&&j==0的时候dp[i][j]=dp[i-1][j]+1;
其他的就是枚举最后一步决策,按照删当前的还是不删当前的来分就行了。
这题搞砸真的非常难过,非常难过
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
const int mod=998244353;
int n;
char str[maxn];
ll dp[maxn][6],w[maxn];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>(str+1);
for(int i=1;i<=n;++i){
cin>>w[i];
}
cout<<str<<endl;
for(int i=1;i<=n;++i){
for(int j=1;j<=4;++j){
if(str[i]=='h'&&j==1){
//dp[i][j]=min(dp[i-1][j-1],dp[i-1][j]+1);
dp[i][j]=dp[i-1][j]+w[i];
}else if(str[i]=='a'&&j==2){
dp[i][j]=min(dp[i-1][j-1],dp[i-1][j]+w[i]);
}else if(str[i]=='r'&&j==3){
dp[i][j]=min(dp[i-1][j-1],dp[i-1][j]+w[i]);
}else if(str[i]=='d'&&j==4){
dp[i][j]=min(dp[i-1][j-1],dp[i-1][j]+w[i]);
}
else{
dp[i][j]=dp[i-1][j];
}
//dp[i][j]=(dp[i][j])%mod;
}
}
cout<<dp[n][4];
return 0;
}
