Codeforces 1096D
现在有一个字符串,你需要用ai的钱去掉这个字符串的第i个位置的字符。现在要使得该字符串中不包含子序列hard。求最小钱数输入第一行一个整数n表示字符串的长度(1<=n<=100000)。 第二行一个给定的字符串。 第三行n个整数a1,a2,a3,...,an(1<=ai<=998244353)。输出输出一个整数表示答案。样例
Input
6 hhardh 3 2 9 11 7 1
Output
5
Input
8 hhzarwde 3 2 6 9 4 8 7 1
Output
4
Input
6 hhaarr 1 2 3 4 5 6
Output
0
说明第一个样例,最开始的两个字符被删除了,所以结果是ardh。 第二个样例,第5个字符被删除所以结果是hhzawde。 第三个样例,不需要删除任何字符。
#include<iostream> #include<cstdio> #include<cstring> #define maxn 100010 #define INF 10000000000000000LL using namespace std; int n,a[maxn]; char s[maxn],st[6]=" hard"; long long dp[maxn][6]; int main(){ scanf("%d",&n); scanf("%s",s+1); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=0;i<=n;i++) for(int j=0;j<=5;j++)dp[i][j]=INF; dp[0][0]=0; for(int i=1;i<=n;i++) dp[i][0]=dp[i-1][0]+(s[i]=='h'?a[i]:0); for(int i=0;i<n;i++){ for(int j=0;j<=4;j++){ if(s[i+1]==st[j+1]){ dp[i+1][j]=min(dp[i+1][j],dp[i][j]+a[i+1]); dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]); } else dp[i+1][j]=min(dp[i+1][j],dp[i][j]); } } long long ans=min(min(dp[n][0],dp[n][1]),min(dp[n][2],dp[n][3])); printf("%lld",ans); return 0; }