题目链接:http://codeforces.com/contest/1096/problem/D
题目分析
这个题是我从别人那里学的方法,在此记录一下我对这个题目的解题方法的理解。
题目要求:给定一个字符串,可以删除任意个字符,且删除某一个字符,有与之对应的消耗,问如何用最少的消耗使得这个字符串中不会出现 hard 。
看到这个题目,第一想法就是删除所有的 h, a , r , d 字符,求最小消耗,但是这样行不通,因为形如 hardhar ,在这里我们只需要删除 最前面的 h,a,r中的任何一个就可以了,但是按照我的那个想法,肯定会把后面的 h, a , r 加进去导致失败。
在代码里面,我们用 h 代表字符串中不出现h的最小消耗, 用 a 代表不出现 ha 的最小消耗, 用 r 代表不出现har 的最小消耗,用 d 代表不出现 hard 的最小消耗
1)为了不出现 h ,那么应当将当前位置以及之前的 h 全部删除,计算消耗。
2)为了不出现 ha , 有两种方法,第一:让当前位置之前不出现 h, 第二种方法:在这个位置之前不出现 ha 的基础上,删除当前位置的 a ,这样就不需要管是否有 h 了,因为已经没有 a 了,无法凑成 ha 。
3)为了不出现 har , 也有两种方法,第一:让当前位置之前不出现 ha , 第二种方法:在这个位置之前不出现har的基础上,删除当前位置的 r , 这样就不需要管是否有 ha 了,因为已经没有 r 了,无法凑成 har 。
4)为了不出现 hard ,也有两种方法 ,第一:让当前位置之前不出现 har , 第二种方法:在这个位置之前不出现hard的基础上,删除当前位置的 r , 这样就不需要管是否有 har 了,因为已经没有 d 了,无法凑成 hard 。
代码区
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include <queue>
using namespace std;
typedef long long ll;
const int Max = 1e5 + 10;
const int inf = 0x3f3f3f3f;
string str;
ll num[Max];
int main()
{
std::ios::sync_with_stdio(false);
int n;
while(cin>>n)
{
cin >> str;
ll h = 0, a = 0, r = 0, d = 0;
for(int i = 0 ;i < n ; i ++)
{
cin >> num[i];
if(str[i] == 'h')
{
h += num[i];
}
else if(str[i] == 'a')
{
a = min(h, a + num[i]);//选择删掉当前位置前面所有的h,还是删除当前位置的a
}
else if (str[i] == 'r')
{
r = min(a, r + num[i]);//选择删掉当前位置前面所有的ha,还是删除当前位置的r
}
else if (str[i] == 'd')
{
d = min(r, d + num[i]);//选择删掉当前位置前面所有的har,还是删除当前位置的d
}
}
printf("%lld\n", d);
}
return 0;
}