CF1096D Easy Problem

题目传送门:CF1096D

洛谷入口

题目大意:

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

数据范围

(circ) (1le nle10^5)
(circ) (1le a_ile998244353)

题解

这题我竟无言以对……
这题在洛谷竟还是蓝题!(划掉)
好了步入正题!
首先这很明显,不能贪心,无后效性,果然是—————
设立状态f[i][j]指此刻(这i的时刻)删到j位(h-1,a-2,r-3,d-4)时的花费最小值
然后开始考虑ztzyfc(状态)(转移)(方程)
f[i][j]来说,可以删j,也可以不删j,于是从两个里取个最小值
即f[i][j]=min(f[i][j-1],f[i][j]+a[i]);(就这个道理)
而对于f[i][1],当然要直接硬让他删,于是直接加
然后,还有什么吗?
哦对就是最后答案取顺下来的f[n][4]啦!
好了准备好了吗?看代码!↓↓↓

AC代码

(本人不担心会T,于是通用流输入输出(不会说是懒)
首先,是一种最复杂的版本,也是看起来最笨的写法:

#include<bits/stdc++.h>//没的说
#define ll  long long
using namespace std;
ll n,a[100010],ans,f[100010][5];
char s[100010];
int main(){
	cin>>n;
	scanf("%s",&s);
	for(ll i=1;i<=n;i++){
		cin>>a[i];
		if(s[i-1]=='h')f[i][1]=f[i-1][1]+a[i],f[i][2]=f[i-1][2],f[i][3]=f[i-1][3],f[i][4]=f[i-1][4];
		else if(s[i-1]=='a')f[i][2]=min(f[i-1][1],f[i-1][2]+a[i]),f[i][1]=f[i-1][1],f[i][3]=f[i-1][3],f[i][4]=f[i-1][4];
		else if(s[i-1]=='r')f[i][3]=min(f[i-1][2],f[i-1][3]+a[i]),f[i][1]=f[i-1][1],f[i][2]=f[i-1][2],f[i][4]=f[i-1][4];
		else if(s[i-1]=='d')f[i][4]=min(f[i-1][3],f[i-1][4]+a[i]),f[i][1]=f[i-1][1],f[i][2]=f[i-1][2],f[i][3]=f[i-1][3];
		else for(int j=1;j<=4;j++)f[i][j]=f[i-1][j];
	}
	cout<<f[n][4];
} 

然后就是稍微结合规律放在了一起,还有map:

#include<bits/stdc++.h>
#define ll  long long
using namespace std;
ll n,a[100010],ans,f[100010][5];
char s[100010];
map<char,int>mp;
int main(){
	mp['h']=1,mp['a']=2,mp['r']=3,mp['d']=4;
	cin>>n;scanf("%s",&s);
	for(ll i=1;i<=n;i++){
		cin>>a[i];
		for(int j=1;j<=4;j++){
			if(mp[s[i-1]]==j){
				if(j!=1)f[i][j]=min(f[i-1][j-1],f[i-1][j]+a[i]);
				else f[i][j]=f[i-1][j]+a[i];
			}
			else f[i][j]=f[i-1][j];
		}
	}
	cout<<f[n][4];
} 

最后还有一种近似玄学的写法
简直了,看代码,不要告诉我这是蓝题,不然题就要被降级了

#include<bits/stdc++.h>
#define ll  long long
using namespace std;
ll n,ans,f[5];
char s[100010];
map<char,int>mp;
int main(){
	mp['h']=1,mp['a']=2,mp['r']=3,mp['d']=4;
	cin>>n;scanf("%s",&s);
	for(ll i=1;i<=n;i++){
		ll x;cin>>x;
		if(s[i-1]=='h')f[1]+=x;
		if(s[i-1]=='a')f[2]=min(f[1],f[2]+x);
		if(s[i-1]=='r')f[3]=min(f[2],f[3]+x);
		if(s[i-1]=='d')f[4]=min(f[3],f[4]+x);
	}
	cout<<f[4];
} 

支持一下吧,关注,点赞,评论都好!

THE END

Reality&Imagine
原文地址:https://www.cnblogs.com/yang-RA-NOI/p/12597726.html