1 条题解

  • 1
    @ 2024-11-16 11:02:54

    令\(dp_{i, j}\) 代表长度为 \(i\),结尾是 \(j\) 的最少操作次数 \((i \in [1,n], j \in [-1, 1])\)

    \[
    \begin{gathered}
    dp_{i,j} = \begin{cases}
    a_i = -1& \begin{cases}
    dp_{i, -1} = dp_{i - 1, -1} \cr
    dp_{i, 0} = +\infty \cr
    dp_{i, 1} = dp_{i - 1, 1} + 2 \cr
    \end{cases} \cr
    a_i = 0 & \begin{cases}
    dp_{i, -1} = dp_{i - 1, -1} + 1 \cr
    dp_{i, 0} = \min(dp_{i - 1, -1}, dp_{i - 1, 0}) \cr
    dp_{i, 1} = dp_{i - 1, 1} + 1 \cr
    \end{cases} \cr
    a_i = 1 & \begin{cases}
    dp_{i, -1} = dp_{i - 1, -1} + 2 \cr
    dp_{i, 0} = dp_{i - 1, -1} + 1 \cr
    dp_{i, 1} = min(dp_{i - 1, -1}, dp_{i - 1, 0}, dp_{i - 1, 1}) \cr
    \end{cases} \cr
    \end{cases}
    \end{gathered}
    \]

    因为数组下标不能为 \(-1\),我们可以将 \(-1, 0, 1\) 替换为 \(0, 1, 2\)。

    std如下:

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int N = 1000010;
    const int INF = 0x3f3f3f3f;
    
    int n;
    int a[N];
    int dp[N][3];
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0), cout.tie(0);
    
        cin >> n;
        for (int i = 1; i <= n; i++) cin >> a[i];
    
        memset(dp, INF, sizeof(dp));
        dp[1][a[1] + 1] = 0;
        for (int i = 2; i <= n; i++) {
            if (a[i] == -1) {
                dp[i][0] = dp[i - 1][0];
                dp[i][2] = dp[i - 1][2] + 2;
            } else if (a[i] == 0) {
                dp[i][0] = dp[i - 1][0] + 1;
                dp[i][1] = min(dp[i - 1][0], dp[i - 1][1]);
                dp[i][2] = dp[i - 1][2] + 1;
            } else if (a[i] == 1) {
                dp[i][0] = dp[i - 1][0] + 2;
                dp[i][1] = dp[i - 1][0] + 1;
                dp[i][2] = min(dp[i - 1][0], min(dp[i - 1][1], dp[i - 1][2]));
            }
        }
        int ans = min(dp[n][0], min(dp[n][1], dp[n][2]));
        if (ans == INF) cout << "Baka\n";
        else cout << ans << '\n';
        return 0;
    }
    
  • 1

信息

ID
1012
难度
9
分类
动态规划 点击显示
标签
(无)
递交数
2
已通过
2
通过率
100%
被复制
1
上传者