给一个字符串,,需要移除一些字符,使得剩下的字符串中不存在“hard”子序列,移除一个字符会产生一定的花费,求最小的花费。
首先肯定是移除同一种字符,不能既删‘h’,又删’a’。dp[i][j]表示考虑到第i个字符时选择移除"hard"中前j个字符的最小的花费
则比如s[i] 是’a’ 时,需要考虑的是前i-1个移除‘h’和‘a’的费用,因为’r’和’d’对当前的’a’无影响,
则dp[i][2] = min(dp[i-1][2] + val[i],dp[i-1][j-1])
否则 dp[i][2] == dp[i-1][2]
#include<bits/stdc++.h>
using namespace std;
#define forn(i,n) for(int i = 0;i<int(n);i++)
typedef long long LL;
const LL INF = 1e18;
LL n,val[101010],dp[101010][6],ans = INF;
char s[101010],t[] = {"hard"};
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
cin>>n>>s+1;
for(int i = 1 ;i<=n;i++) cin>>val[i];
for(int i = 0;i<=n;i++)
for(int j = 0;j<5;j++) dp[i][j] = INF;
for(int i = 1;i<5;i++) dp[0][i] = 0 ;
for(int i = 1;i<=n;i++)
for(int j = 1;j<5;j++)
if(s[i] != t[j-1]) dp[i][j] = dp[i-1][j];
else dp[i][j] = min(dp[i-1][j-1],dp[i-1][j]+val[i]);
for(int i = 1 ;i<5;i++)
ans = min(ans,dp[n][i]);
cout<<ans;
return 0;
}