http://codeforces.com/problemset/problem/1096/D
char c=" hard";
dp[i][j]表示前i个字符不含有c[1]至c[j]子序列
状态转移方程:如果s[i]不为特定字符,dp[i][j]=dp[i-1][j]。
否则dp[i][j]=min(dp[i-1][j]+val[i],dp[i-1][j-1])。
若为特定字符,为保证dp数组有效,要么选择删除该字符val[i],并且i前不含有特定字符子序列dp[i-1][j]。
或是选择不删除该字符,并且i前不含有j前的特定字符子序列dp[i-1][j-1]。
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100005
#define ll long long
#define inf 1e16
char s[MAXN];
ll num[MAXN];
ll dp[MAXN][5];
char c[]=" hard";
int main(){
int n;
scanf("%d",&n);
scanf("%s",s+1);
for(int i=1;i<=n;i++){
scanf("%I64d",num+i);
dp[i][0]=inf;
}
dp[0][0]=inf;
for(int i=1;i<=n;i++){
for(int j=1;j<=4;j++){
if(s[i]!=c[j]){
dp[i][j]=dp[i-1][j];
continue;
}
dp[i][j]=min(dp[i-1][j-1],dp[i-1][j]+num[i]);
}
}
printf("%I64d\n",dp[n][4]);
return 0;
}