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;
    }
  • 相关阅读:
    串口通信
    无法安装SQL提示文件被挂起
    flash图片幻灯片浏览
    document.all与WEB标准
    在新窗口中打开页面 的asp.net后台代码
    sql 触发器
    无技术含量的正则表达式笔记
    两个FTP服务器之间传送数据
    repeater嵌套
    登录
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6401445.html
Copyright © 2011-2022 走看看