Codeforces 1096D

给一个字符串,,需要移除一些字符,使得剩下的字符串中不存在“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; 
} 

猜你喜欢

转载自blog.csdn.net/winhcc/article/details/88920223