題目分析
這個題是我從別人那裏學的方法,在此記錄一下我對這個題目的解題方法的理解。
題目要求:給定一個字符串,可以刪除任意個字符,且刪除某一個字符,有與之對應的消耗,問如何用最少的消耗使得這個字符串中不會出現 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;
}