题目链接:http://codeforces.com/problemset/problem/1096/D
https://vjudge.net/contest/362376#problem/H
题意:给定一个字符串s,以及s每个字符对应的歧义值。删除第i个字符会造成a[i]点歧义,现在要删除某些字符使得s中不会含有hard(hard各字符可以不在同一地方,但顺序要为h a r d)
解题思路:
利用dp[i][j] 表示i长度的字符串,含有hard前j个字符的最小歧义值
状态方程:
最后直接遍历dp[n][i]寻找最小值即可。
#include<iostream>
#include<cstdio>
#include<string>
#include<string.h>
using namespace std;
#define ll long long
#define inf 1e18
int n;
char str[110000] ;
ll a[110000];
char hard[5]={'@','h','a','r','d'};
ll dp[110000][5];
int main()
{
cin>>n;
scanf("%s",str+1);
int j=0;
for(int i=0;i<=4;i++)
dp[0][i]=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
for(int j=0;j<=4;j++)
dp[i][j]=inf;
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<4;j++)
{
//如果未出现hard[j+1]字符就不会打破dp[i-1][j],所以直接传递状态
if(str[i]!=hard[j+1])
dp[i][j]=min(dp[i][j],dp[i-1][j]);
else
{
//删去str[i],使得hard出现最大长度仍然为j
dp[i][j]=min(dp[i][j],dp[i-1][j]+a[i]);
//保留str[i],使得hard出现最大长度变为j+1
dp[i][j+1]=min(dp[i][j+1],dp[i-1][j]);
}
}
}
ll ans=dp[n][0];
for(int i=1;i<4;i++)
ans=min(ans,dp[n][i]);
cout<<ans<<endl;
return 0;
}