首页 > 其他 > 详细

CF1096D 题解

时间:2020-04-10 13:20:33      阅读:63      评论:0      收藏:0      [点我收藏+]

题目链接

可爱的题目大意

给出一个长度为\(n\)的字符串,如果这个字符串中含有子序列\(“hard”\),那么这个字符串就很\(hard\)。你不希望这个字符串很\(hard\),所以想要从中删掉几个字符使他不\(hard\)
例:\(hard\),?\(hzazrzd\),?\(haaaaard\) 都很 \(hard\),而 \(har\),?\(hart\)\(drah\)\(hard\)
删掉在原字符串中的第\(i\)个字符需要花费\(a_i\)的代价,求最小代价。

\(Solution\)

我们令\(f_{i,j}\)表示当前\(dp\)到第\(i\)位,清到\(hard\)的第几位(用当前位置消掉\(hard\)
对于一个可能的子序列\(hard\),我们只需要在其中任意删掉一个字符就可以消灭整个字符串,那么有
\(f_{i,j}=min(f_{i-1,j-1},f_{i-1,j}+a_i)\)
然后我们发现第\(i\)层的状态只和\(i-1\)层的状态有关,于是就可以省掉一维(其实省掉一维的做法更好理解?)

\(Code\)

#include<bits/stdc++.h>
using namespace std;
namespace my_std
{
	typedef long long ll;
	typedef double db;
	#define pf printf
	#define pc putchar
	#define fr(i,x,y) for(register ll i=(x);i<=(y);++i)
	#define pfr(i,x,y) for(register ll i=(x);i>=(y);--i)
	#define go(x) for(ll i=head[u];i;i=e[i].nxt)
	#define enter pc(‘\n‘)
	#define space pc(‘ ‘)
	#define fir first
	#define sec second
	#define MP make_pair
	const ll inf=0x3f3f3f3f;
	const ll inff=1e15;
	inline ll read()
	{
		ll sum=0,f=1;
		char ch=0;
		while(!isdigit(ch))
		{
			if(ch==‘-‘) f=-1;
			ch=getchar();
		}
		while(isdigit(ch))
		{
			sum=sum*10+(ch^48);
			ch=getchar();
		}
		return sum*f;
	}
	inline void write(ll x)
	{
		if(x<0)
		{
			x=-x;
			pc(‘-‘);
		}
		if(x>9) write(x/10);
		pc(x%10+‘0‘);
	}
	inline void writeln(ll x)
	{
		write(x);
		enter;
	}
	inline void writesp(ll x)
	{
		write(x);
		space;
	}
}
using namespace my_std;
const ll N=1e5+50;
ll n,a[N],f[5];
char s[N];
int main(void)
{
	n=read();
	scanf("%s",s+1);
	fr(i,1,n) a[i]=read();
	fr(i,1,n)
	{
		if(s[i]==‘h‘) f[1]+=a[i];
		else if(s[i]==‘a‘) f[2]=min(f[2]+a[i],f[1]);
		else if(s[i]==‘r‘) f[3]=min(f[3]+a[i],f[2]);
		else if(s[i]==‘d‘) f[4]=min(f[4]+a[i],f[3]);
	}
	writeln(f[4]);
	return 0;
}

CF1096D 题解

原文:https://www.cnblogs.com/lgj-lgj/p/12672454.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!