[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可以被剔除(不懂的你该好好想了)
然后我们就用到单调队列啦啦啦~
题意看起来很普通 可是实际上却不是。
好像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; }
相关文章推荐
- bzoj1233: [Usaco2009Open]干草堆tower
- bzoj 1233: [Usaco2009Open]干草堆tower 【想法题】
- 1233: [Usaco2009Open]干草堆tower
- BZOJ1233: [Usaco2009Open]干草堆tower
- BZOJ 1233: [Usaco2009Open]干草堆tower
- [BZOJ1233][Usaco2009Open]干草堆tower(dp+决策单调性)
- bzoj1233 [Usaco2009Open]干草堆tower(单调队列优化DP)
- bzoj1233: [Usaco2009Open]干草堆tower 单调队列优化dp
- BZOJ 1233: [Usaco2009Open]干草堆tower
- BZOJ1233 [Usaco2009Open]干草堆tower 【单调队列优化dp】
- bzoj1233[Usaco2009Open]干草堆tower 单调队列优化dp
- bzoj 1233: [Usaco2009Open]干草堆tower
- bzoj1233[Usaco2009Open]干草堆tower
- BZOJ1233: [Usaco2009Open]干草堆tower
- 【BZOJ1233】【USACO2009Open】干草堆tower
- bzoj1233 [Usaco2009Open]干草堆tower 【单调队列dp】
- Bzoj1233 [Usaco2009Open]干草堆tower
- bzoj1233 [Usaco2009Open]干草堆tower
- [BZOJ1233] [Usaco2009Open]干草堆tower
- [BZOJ 1233][Usaco2009Open]干草堆tower:单调队列