bzoj 1233: [Usaco2009Open]干草堆tower 【想法题】

$f[i][j]$表示用前$i$包干草 且最顶层为第$j+1$包到第$i$包 所能达到的最大高度

----------------------------------------------------------------------------------------------------

3

2 1 4

----------------------------------------------------------------------------------------------------

$f[i]=min(sum[j-1]-sum[i-1])$,$(j>i,f[j]<=sum[j-1]-sum[i-1])$

----------------------------------------------------------------------------------------------------

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define rep(i,n) for(int i=1;i<=n;++i)
#define imax(x,y) (x>y?x:y)
#define imin(x,y) (x<y?x:y)
using namespace std;
const int N=100010;
int sum[N],f[N],g[N],q[N];
int n;
int main()
{
scanf("%d",&n);
rep(i,n)
{
scanf("%d",&sum[i]);
sum[i]+=sum[i-1];
}
int ifront=1,itail=1;
q[1]=n+1;
for(int i=n;i;--i)
{
while(ifront<itail&&sum[q[ifront+1]-1]-sum[i-1]>=f[q[ifront+1]])
++ifront;
f[i]=sum[q[ifront]-1]-sum[i-1];
g[i]=g[q[ifront]]+1;
while(ifront<=itail&&sum[q[itail]-1]-f[q[itail]]<=sum[i-1]-f[i])--itail;
q[++itail]=i;
}
printf("%d",g[1]);
return 0;
}

posted @ 2015-07-16 11:16 sagitta 阅读(...) 评论(...) 编辑 收藏