zoukankan      html  css  js  c++  java
  • bzoj1233[Usaco2009Open]干草堆tower 单调队列优化dp

    1233: [Usaco2009Open]干草堆tower

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 983  Solved: 464
    [Submit][Status][Discuss]

    Description

    奶牛们讨厌黑暗。 为了调整牛棚顶的电灯的亮度,Bessie必须建一座干草堆使得她能够爬上去够到灯泡 。一共有N大包的干草(1<=N<=100000)(从1到N编号)依靠传送带连续的传输进牛棚来。第i包干草有一个 宽度W_i(1<=w_i<=10000)。所有的干草包的厚度和高度都为1. Bessie必须利用所有N包干草来建立起干草堆,并且按照他们进牛棚的顺序摆放。她可以相放多少包就放 多少包来建立起tower的地基(当然是紧紧的放在一行中)。接下来他可以放置下一个草包放在之前一级 的上方来建立新的一级。注意:每一级不能比下面的一级宽。她持续的这么放置,直到所有的草包都被安 置完成。她必须按顺序堆放,按照草包进入牛棚的顺序。说得更清楚一些:一旦她将一个草包放在第二级 ,她不能将接下来的草包放在地基上。 Bessie的目标是建立起最高的草包堆。

    Input

    第1行:一个单一的整数N。 第2~N+1行:一个单一的整数:W_i。

    Output

    第一行:一个单一的整数,表示Bessie可以建立的草包堆的最高高度。

    Sample Input

    3
    1
    2
    3

    Sample Output

    2
    输出说明:
    前两个(宽度为1和2的)放在底层,总宽度为3,在第二层放置宽度为3的。
    +----------+
    | 3 |
    +---+------+
    | 1 | 2 |
    +---+------+

    HINT

     

    Source

     

    很扯淡的一道题目。
    可以看出这道题最后形成的图形应该是金字塔形的,而对于材料相同金字塔来说 底部越窄形成的高度越高
    这个通过感性的方式理解应该是显然的,但是又感觉有点玄乎,感觉这篇博客的证明很有道理
    http://blog.csdn.net/u010336344/article/details/52821271

    所以得到一个结论,对于同一层来说 这一层越窄方案就越优
    由于上面的必须不宽于下面,考虑倒着dp
    f[i]=sum[i]-sum[j] 满足sum[i]-sum[j]>=f[j]即sum[i]>=sum[j]+f[j]
    要让f[i]最小必须让j尽量大并且j满足条件
    可以发现,sum[i]>=sum[j]+f[j]中sum[i]是不变的,那么后面的部分越小越可以满足
    故 若有 k<j && sum[k]+f[k]>=sum[j]+f[j] k是肯定不会被转移的
    因此可以维护一个单调递增的队列来转移dp
    dp时记录g[i]来表示搭到第i个最高搭的层数

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define N 100005
     6 using namespace std;
     7 int n,a[N],sum[N],q[N],f[N],g[N];
     8 int main(){
     9     scanf("%d",&n);
    10     for(int i=n;i;i--)scanf("%d",&a[i]);
    11     for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
    12     int l=1,r=1;
    13     for(int i=1;i<=n;i++){
    14          while(l<r&&sum[i]>=sum[q[l+1]]+f[q[l+1]])l++;//满足条件的情况下j越大 f[i]越小
    15          int j=q[l];g[i]=g[j]+1;f[i]=sum[i]-sum[j];
    16          while(l<r&&sum[q[r]]+f[q[r]]>=sum[i]+f[i])r--;
    17          q[++r]=i;
    18     }
    19     printf("%d
    ",g[n]);return 0;
    20 }
  • 相关阅读:
    装饰器模式(学习笔记10)
    软件设计七大原则 (学习笔记2)
    设计模式(学习笔记1)
    桥接模式 (学习笔记9)
    Mini2440裸机开发之LCD基础
    配置中心java客户端实现
    高效CSS写法
    整理电脑里面的前端开发中的小Tips【及时更新】
    IE6 position:fixed (固定定位)的解决方案
    jquery 文档操作
  • 原文地址:https://www.cnblogs.com/wsy01/p/8109598.html
Copyright © 2011-2022 走看看