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;
    }
  • 相关阅读:
    ES 入门记录之 match和term查询的区别
    ElasticSearch 学习记录之Text keyword 两种基本类型区别
    ES 记录之如何创建一个索引映射,以及一些设置
    娱乐至死 读书笔记
    ES 入门之一 安装ElasticSearcha
    王二的经济学故事 读书笔记
    redis特性 存储 API 集群 等
    Linux 卸载 openjdk
    Linux 下面解压.tar.gz 和.gz文件解压的方式
    本地连接 vmware服务器
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6401445.html
Copyright © 2011-2022 走看看