(DP) POI Bytecomputer

Bytecomputer

Memory limit: 128 MB

A sequence of  integers  from the set  is given. The bytecomputer is a device that allows the following operation on the sequence: incrementing  by  for any . There is no limit on the range of integers the bytecomputer can store, i.e., each  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 ) with the minimum number of operations.

Input

The first line of the standard input holds a single integer  (), the number of elements in the (bytecomputer‘s) input sequence.

The second line contains  integers  () that are the successive elements of the (bytecomputer‘s) input sequence, separated by single spaces.

In tests worth 24% of the total points it holds that , and in tests worth 48% of the total points it holds that .

Output

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.

Example

For the input data:

6
-1 1 0 -1 0 1

the correct result is:

3

Explanation of the example: with three operations, the bytecomputer can obtain the sequence .

Sample grading tests:

  • 0grade, a small test with the answer BRAK;
  • 1grade, a small test with the answer ;
  • 2grade, all the elements in the sequence equal ;
  • 3grade;
  • 4grade and .

Task author: Jacek Tomasiewicz.

题意:

a[x]=a[x-1]+a[x]要让序列递增

那么无非是 -1 -1 -1 -1 0 0 0  0 0  0 0 1 1 1 1 1 1 11 11 1 1

f[i][j]填写到i个数字这个数字为j然后转移就好了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<vector>
#include<stack>
#define INF 100000000
using namespace std;
int dp[1000005][3],n,a[1000005];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=2;j++)
            dp[i][j]=INF;
    }
    dp[1][a[1]+1]=0;
    for(int i=1;i<n;i++)
    {
        for(int j=0;j<=2;j++)
        {
            for(int k=0;k<=2;k++)
            {
                if(dp[i][j]==INF)
                    continue;
                int newj;
                newj=a[i+1]+(j-1)*k;
                if(newj>=-1&&newj<=1&&newj>=(j-1))
                    dp[i+1][newj+1]=min(dp[i+1][newj+1],dp[i][j]+k);
            }
        }
    }
    int ans=INF;
    for(int i=0;i<=2;i++)
        ans=min(ans,dp[n][i]);
    if(ans==INF)
        printf("BRAK\n");
    else
        printf("%d\n",ans);
    return 0;
}

  

时间: 2024-10-16 10:10:40

(DP) POI Bytecomputer的相关文章

Nescafe27 探险队(dp)

之前在BZOJ群里请教了下各位神牛..大概都得出了需要按某个端点排序.. 首先把一开始就不合法的人(即a+b>=n的人删除),然后得出每个人的排名范围:(b,n-a] 考虑dp[i]表示前i个人中最多有多少个人没说谎 按n-a从小到大排序,则n-a的顺序满足dp的拓扑序,当i取得n-a的时候,寻找区间相同的数量m,那么dp[i]=max(dp[i-1],dp[j]+min(m,N-Aj-Bj)) dp效率是O(n) #include<set> #include<map> #i

[POI 2013]Bytecomputer(DP)

题目链接 http://main.edu.pl/en/archive/oi/20/baj 题目大意 给你一个长度为n的序列a,序列里每个元素要么是0,要么是-1,要么是1,每次操作可以让a[x]=a[x]+a[x?1],问至少要做多少次操作,才能让整个序列变成非降序列 思路 可以发现,最终的序列是一定是-1 -1 -1--1 -1 -1 0 0 0-0 0 0 1 1 1-1 1 1的形式,肯定没有2或者更大的数字,因为出现这样大的数字是毫无必要的,会增加操作次数.那么可以通过DP解决此题,用f

BZOJ 4726 POI 2017 Sabota? 树形DP

4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved: 49[Submit][Status][Discuss] Description 某个公司有n个人, 上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他下属(直接或者间接, 不包括他自己)中叛徒占的比例超过x,那么这个人也会变成叛徒,并且他的所有下属都会变成叛徒

BZOJ 3831 POI 2014 Little Bird 单调队列DP

题目大意:给出一片树林,树排成一排,每一棵树都有一个高度.从地一棵树出发,每次可以跳到i+k棵之前,跳到小于自己高度的树上不需要花费体力,反之需要花费一点体力,问到最后一棵树最少需要多少体力. 思路:简单DP方程:f[i] = min{f[j] + (height[i] >= height[j])} 然后发现数据范围只有O(n)可以过. 维护单调队列,队列中按照f单调递减,队尾按照时间往出弹. 当f值相同的时候,高度较高的优先. CODE: #include <queue> #inclu

POI 2014 HOTELS (树形DP)

题目链接 HOTELS 依次枚举每个点,以该点为中心扩展. 每次枚举的时候,从该点的儿子依次出发,搜完一个儿子所有的点之后进行答案统计. 这里用了一个小trick. 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define rep(i, a, b) for(int i(a); i <= (b); ++i) 6 #define for_edge(i, x) for(int i = H[x]; i; i = X[i]) 7

BZOJ 3522 POI 2014 Hotel 树形DP

题目大意 给出一棵树,问选择三个点,使得这三个点相互的距离相等的方案有多少种. 思路 这三个点肯定不能再一条链上, 那么就肯定能够确定一个中心点,使得三个点到这个中心点的距离都相等. 之后我们就可以枚举这个中心点,对于每个深度统计一下就可以了.虽然看起来像是O(n3)的,但是跑的飞起啊. CODE #define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> #include <iostream>

【题解】Luogu P3509 [POI 2010] ZAB-Frog 倍增dp

单调队列处理第k远的点 倍增跳点 滚(动数组)一维空间就能开下了 注意$m≤10^{18}$的读入 code 1 #include <bits/stdc++.h> 2 using namespace std; 3 namespace gengyf{ 4 #define ll long long 5 const int maxn=1e6+10; 6 inline ll read(){ 7 ll x=0,f=1; 8 char c=getchar(); 9 while(c<'0'||c>

【BZOJ-1974】auction代码拍卖会 DP + 排列组合

1974: [Sdoi2010]auction 代码拍卖会 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 305  Solved: 122[Submit][Status][Discuss] Description 随着iPig在P++语言上的造诣日益提升,他形成了自己一套完整的代码库.猪王国想参加POI的童鞋们都争先恐后问iPig索要代码库.iPig不想把代码库给所有想要的小猪,只想给其中的一部分既关系好又肯出钱的小猪,于是他决定举行了一个超大型拍

BZOJ 1974: [Sdoi2010]auction 代码拍卖会( dp )

在1, 11, 111……中选<=8个, + 11..(n个1)拼出所有可能...这些数mod p至多有p中可能, 找出循环的处理一下. 那么dp就很显然了...dp(i, j, k)表示前i种选出了j个, 组合出的数mod p = k, 然后递推一下就好了. ----------------------------------------------------------------------- #include<cstdio> #include<cstring> #i