卧薪尝胆,厚积薄发。
POI2013 BAJ-Bytecomputer
Date: Wed Sep 19 11:42:07 CST 2018
In Category:
NoCategory
Description:
给一个只包含
$-1,0,1$
的数列,每次操作可以让
$a[i]+=a[i-1]$
,求最少操作次数使得序列单调不降。
$1\le n \le 1000000$
Solution:
设
$f[i][0/1/2]$
表示第
$i$
位最后被加成了
$-1/0/1$
的最少操作次数,转移时分类讨论一下,注意
$a[i]+=a[i-1]$
的
$a[i-1]$
是被加完之后的,初值为
$f[1][a[1]]=0$
。
Code:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int n;
#define MAXN 1000010
int a[MAXN];
int f[MAXN][3];
int main()
{
scanf("%d",&n);
for(int i = 1;i <= n;++i)scanf("%d",&a[i]);
memset(f,0x3f,sizeof(f));
f[1][a[1] + 1] = 0;
for(int i = 2;i <= n;++i)
{
if(a[i] == -1)
{
f[i][0] = f[i - 1][0];
f[i][2] = f[i - 1][2] + 2;
}
if(a[i] == 0)
{
f[i][0] = f[i - 1][0] + 1;
f[i][1] = min(f[i - 1][1],f[i - 1][0]);
f[i][2] = f[i - 1][2] + 1;
}
if(a[i] == 1)
{
f[i][0] = f[i - 1][0] + 2;
f[i][1] = f[i - 1][0] + 1;
f[i][2] = min(f[i - 1][2],min(f[i - 1][1],f[i - 1][0]));
}
}
int ans = min(f[n][2],min(f[n][1],f[n][0]));
if(ans == 0x3f3f3f3f)puts("BRAK");
else cout << ans << endl;
return 0;
}
In tag:
DP-DP
Copyright © 2020
wjh15101051
ღゝ◡╹)ノ♡