比赛时高二dalaoLRZ提醒我是状压,然而,我还是没AC (汗
其实是一道很基础的线性dp
\(f_{i,j}\) 表示序列第 \(i\) 个字符时对于 \(string\ st="hard"\) 的前缀 \(0\) ~ \(j-1\) 最小的ambiguity值
边界: \(f_0=0\) ,其它 \(f\) 值均为 \(∞\)
状态转移方程:
若 \(s_i≠st_{j-1}\) ,则 \(f_{i,j}=f_{i-1,j}\) ;
否则,\(f_{i,j}=min(f_{i-1,j-1},f_{i-1,j}+a_i)\) 。
目标: \(min(f_n)\)
注意开long long(或许不会爆int,开了保险)
上代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 100006;
const string st = "hard";
int n;
char s[N];
ll a[N], f[N][5];
int main() {
cin >> n;
scanf("%s", s + 1);
for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
memset(f, 0x3f, sizeof(f));
for (int i = 1; i < 5; i++) f[0][i] = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j < 5; j++)
if (s[i] != st[j-1]) f[i][j] = f[i-1][j];
else f[i][j] = min(f[i-1][j-1], f[i-1][j] + a[i]);
ll ans = f[n][0];
for (int i = 1; i < 5; i++) ans = min(ans, f[n][i]);
cout << ans << endl;
return 0;
}