zoukankan      html  css  js  c++  java
  • 【bzoj3427】Poi2013 Bytecomputer dp

    题目描述

    A sequence of N  integers I1,I2…In from the set {-1,0,1} is given. The bytecomputer is a device that allows the following operation on the sequence: incrementing I(i+1) by I(i) for any 1<=I<=N. There is no limit on the range of integers the bytecomputer can store, i.e., each I(i) can (in principle) have arbitrarily small or large value.
    Program the bytecomputer so that it transforms the input sequence into a non-decreasing sequence (i.e., such that I1<=I2<=…I(n)) with the minimum number of operations.
    给定一个{-1,0,1}组成的序列,你可以进行x[i]=x[i]+x[i-1]这样的操作,求最少操作次数使其变成不降序列。

    输入

    The first line of the standard input holds a single integer N(1<=N<=1000000) , the number of elements in the (bytecomputer's) input sequence.
    The second line contains N  integers I1,I2…I(n) Ii from set {-1,0,1}  that are the successive elements of the (bytecomputer's) input sequence, separated by single spaces.

    输出

    The first and only line of the standard output should give one integer, the minimum number of operations the bytecomputer has to perform to make its input sequence non-decreasing, of the single word BRAK (Polish for none) if obtaining such a sequence is impossible.

    样例输入

    6
    -1 1 0 -1 0 1

    样例输出

    3


    题解

    显而易见,最后的数列一定只包含-1、0和1.

    于是用dp。

    f[i][p]表示第i个数为p-1时的最小次数。

    然后判断能否改变即可。

    注意不要除0,实在不行也可以用多条if else语句判断。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int f[1000001][3] , a[1000001];
    int main()
    {
        int n , i , j , k;
        scanf("%d" , &n);
        for(i = 1 ; i <= n ; i ++ )
            scanf("%d" , &a[i]);
        memset(f , 0x3f , sizeof(f));
        f[1][a[1] + 1] = 0;
        for(i = 2 ; i <= n ; i ++ )
            for(j = -1 ; j <= 1 ; j ++ )
                for(k = -1 ; k <= j ; k ++ )
                    if(j == a[i] || ((j - a[i]) * k > 0 && (j - a[i]) % k == 0))
                        f[i][j + 1] = min(f[i][j + 1] , f[i - 1][k + 1] + (k ? (j - a[i]) / k : 0));
        i = min(f[n][0] , min(f[n][1] , f[n][2]));
        if(i > 2 * n)
            printf("BRAK
    ");
        else
            printf("%d
    " , i);
        return 0;
    }
  • 相关阅读:
    使用 JDBC 驱动程序
    (转载)SQL Server 2008 连接JDBC详细图文教程
    (转载)VB中ByVal与ByRef的区别
    (转载)Java里新建数组及ArrayList java不允许泛型数组
    在VS2008环境下编写C语言DLL,并在C++和C#项目下调用 (转载)
    近期计划
    在服务器上使用python-gym出现的关于显示的问题
    字符串匹配
    Ubuntu18.04 桌面系统的个人吐槽(主要是终端)
    Ubuntu18.04上安装N卡驱动、CUDA、CUDNN三连
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6401445.html
Copyright © 2011-2022 走看看