您的位置:首页 > 运维架构

[Usaco2009Open]干草堆tower 一字不落的转载

2017-02-25 13:51 429 查看
这道题还真是像黄学长说的一样的神题啊。。。

题意看起来很普通 可是实际上却不是。

好像DP 好像贪心 好像想法题,后来发现都需要。



怎么觉得我最近做的题都要个证明啊。。。实在不懂的就yy一下吧 差不多就是酱

接着不难发现倒推会发现单调

这样之后就可以得到O(N^2)的DP  

f[i]:用i~n来构成的堆,最靠下的一层最短是多少 
g[i]:状态f[i]的最大高度 
f[i]=min{sum[j−1]−sum[i−1]}   (i<j≤n,f[j]≤sum[j−1]−sum[i−1]) 

然后我们可以发现

当有两个决策点j<k且sum[k−1]−f[k]≤sum[j−1]−f[j]时,k可以被剔除(不懂的你该好好想了)

然后我们就用到单调队列啦啦啦~

#include<cstdio>
using namespace std;
const int N=100010;
int s
,q
,h,t,g
,f
;
int main()
{
int n,i,x;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&x),s[i]=s[i-1]+x;
h=t=1; q[t]=n+1;
for(i=n;i;i--)
{
while(h<t && f[q[h+1]]<=s[q[h+1]-1]-s[i-1])h++;
x=q[h];
g[i]=g[x]+1,f[i]=s[x-1]-s[i-1];
while(h<t && f[i]-s[i-1]<f[q[t]]-s[q[t]-1])t--;
q[++t]=i;
}
printf("%d\n",g[1]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: