【CodeForces - 1096D】Easy Problem(dp,思维)

题目大意:

现在有一个由小写字母组成的字符串,去掉这个字符串的第i个位置的字符会有ai的代价。你的任务是去掉这个字符串中的一些字符使得该字符串中不包含子序列hard,且去掉字符的代价之和尽可能小。

输入

第一行一个整数n表示字符串的长度(1<=n<=100000)。 第二行一个给定的字符串。 第三行n个整数a1,a2,a3,...,an(1<=ai<=998244353)。

输出

输出一个整数表示答案。

Examples

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

Note

In the first example, first two characters are removed so the result is ardh.

In the second example, 55-th character is removed so the result is hhzawde.

In the third example there's no need to remove anything.

解题报告:

考虑dp。首先有效字符只有hard四个字符,考虑转移。

如果出现不合法序列,最后一个字符肯定是d,并且前面按照顺序出现了har,所以可以设定dp[n][4]代表前缀不出现h,不出现ha,不出现har,不出现hard的最小代价。最后dp[n][4]就是答案。

转移就是对于四个字符中的每一个字符,假设是d,那么更新dp[i][4],则选择删除或者不删除这个字符,如果删除则从dp[i-1][4]+a[i]转移过来,如果不删除则需要保证前i-1个字符不能有har,所以dp[i-1][3]转移过来。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
char s[MAX];
int n,a[MAX];
ll dp[MAX][5];//h a r d
int main()
{
	memset(dp,0x3f,sizeof dp);
	for(int j = 1; j<=4; j++) dp[0][j] = 0; 
	cin >> n;
	cin >> s+1;
	for(int i = 1; i<=n; i++) cin >> a[i];
	for(int i = 1; i<=n; i++) {
		for(int j = 1; j<=4; j++) dp[i][j] = dp[i-1][j];
		if(s[i] == 'h') dp[i][1] = dp[i-1][1]+a[i];
		if(s[i] == 'a') dp[i][2] = min(dp[i-1][2]+a[i],dp[i-1][1]);
		if(s[i] == 'r') dp[i][3] = min(dp[i-1][3]+a[i],dp[i-1][2]);
		if(s[i] == 'd') dp[i][4] = min(dp[i-1][4]+a[i],dp[i-1][3]);
	}
	printf("%lld\n",*min_element(dp[n]+1,dp[n]+5));
	return 0 ;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值