CF1096D Easy Problem

时间:2023-01-17 02:27:27

题目地址:CF1096D Easy Problem

比赛时高二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;
}