首页 > 其他分享 >P3558 BAJ-Bytecomputer

P3558 BAJ-Bytecomputer

时间:2022-12-26 20:33:23浏览次数:60  
标签:Bytecomputer int printf BRAK BAJ P3558

P3558 BAJ-Bytecomputer

题意:

给定一个长度为 \(n\) 的只包含 \(-1,0,1\) 的数列 \(a\) ,每次操作可以使 \(a_i \leftarrow a_i + a_{I - 1}\) ,求最少操作次数使得序列单调不降。如果不可能通过改操作使得序列不下降,输出 BRAK

思路:

每个位置一共有三种可能,很明显的动态规划问题,定义 \(f[i][j]\) 为遍历到第 \(i\) 个点,当前数值为 \(j\) 时需要的最少花费。
剩下的参考:https://www.luogu.com.cn/blog/NKU-AI/solution-p3558

实现:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5, INF = 1e9;
int f[N][4];
int a[N];
int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for (int i = 0; i <= n; i++)
        for (int j = 0; j < 4; j++)
            f[i][j] = INF;

    f[1][a[1] + 1] = 0;
    for (int i = 2; i <= n; i++)
    {
        if (a[i] == -1)
        {
            // 当前为 -1 的话,前面的最大值也为 -1 时直接转移
            f[i][0] = f[i - 1][0];
            // 没必要让当前变成0,增加了负担又不能为后面贡献1
            // 变成 1 的话,需要前一个是 1 ,并且操作 2 次
            f[i][2] = f[i - 1][2] + 2;
        }
        else if (a[i] == 0)
        {
            // 当前变成 -1 的话,需要前一个是 -1 然后操作一次
            f[i][0] = f[i - 1][0] + 1;
            // 当前保持 0 的话,前面可以是 -1 或者 0
            f[i][1] = min(f[i - 1][1], f[i - 1][0]);
            // 当前变 1 需要前面是1并且操作一次
            f[i][2] = f[i - 1][2] + 1;
        }
        else if (a[i] == 1)
        {
            // 变成 -1
            f[i][0] = f[i - 1][0] + 2;
            // 变成 0
            f[i][1] = f[i - 1][0] + 1;
            // 变成 1
            f[i][2] = min({f[i - 1][0], f[i - 1][1], f[i - 1][2]});
        }
    }
    int res = min({f[n][0], f[n][1], f[n][2]});
    if (res >= INF)
        printf("BRAK\n");
    else
        printf("%d\n", res);
    return 0;
}

标签:Bytecomputer,int,printf,BRAK,BAJ,P3558
From: https://www.cnblogs.com/zxr000/p/17006788.html

相关文章