CF1096D .Easy Problem(字符串+dp)

题目链接: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;

}
原创文章 65 获赞 3 访问量 2102

猜你喜欢

转载自blog.csdn.net/littlegoldgold/article/details/104967212