Dark
Description
一个长度为
n
的非负整数序列
问最少的操作次数。
Data Constraint
Solution
我们记状态
f
[
发现这样子转移到的状态只与当前状态有关,再维护一个后缀最值转移即可。
方程转移式很容易推,实在不懂可以看看标程。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,j,l) for(int i=j;i<=l;i++)
#define fd(i,j,l) for(int i=j;i>=l;i--)
using namespace std;
typedef long long ll;
const ll N=11e4,M=11e5;
int f[2][M][2],a[N],q[N],g[M];
int n,m,j,k,l,i;
void read(int &o)
{
o=0; char ch=' ';
for(;ch<'0'||ch>'9';)ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar())o=o*10+ch-48;
}
int min(int a,int b)
{if(a<b)return a;else return b;}
int max(int a,int b)
{if(a>b)return a;else return b;}
int main()
{
cin>>n;
fo(i,1,n)read(a[i]),q[i]=q[i-1]+a[i];
int u=0,v;
fo(i,1,n)
{
v=1-u;
fo(l,0,a[i])f[v][l][0]=f[v][l][1]=2*q[n];
g[a[i-1]+1]=q[i-1]/2+2;
fd(l,a[i-1],0)g[l]=min(g[l+1],f[u][l][0]);
fo(l,max(0,a[i]-a[i-1]+1),a[i])
f[v][l][1]=g[a[i]-l+1]+a[i]-l;
fo(l,0,min(a[i-1],a[i]))
f[v][a[i]-l][0]=min(min(f[u][l][0],f[u][l][1])+l,f[v][a[i]-l][0]);
u=v;
}
int ans=q[n]/2;
fo(i,0,a[n])ans=min(ans,f[u][i][0]);
ans=min(ans,f[u][0][1]);
printf("%d",ans);
}