BZOJ1233: [Usaco2009Open]干草堆tower

1233: [Usaco2009Open]干草堆tower

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 586  Solved: 254
[Submit][Status]

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

Gold

题解:

发现n^2 的dp很好想 f[i]表示以i为所在层最后一个最多能多少层,g[i]表示此时的宽度

然后 f[i]=max(f[j])+1 s[i]-s[j]>g[j]

然后。。。

当你发现优化不了的时候题解会说:显然,由贪心可知。。。

如下:

单调性dp。可以用贪心证明:当第i层的宽度为w时,则第i-1层的宽度应尽量最小。

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

贪心是最终boss啊

不过我还是不懂为啥啊!!!!!!!!

代码:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<iostream>
 7 #include<vector>
 8 #include<map>
 9 #include<set>
10 #include<queue>
11 #include<string>
12 #define inf 1000000000
13 #define maxn 101000
14 #define maxm 500+100
15 #define eps 1e-10
16 #define ll long long
17 #define pa pair<int,int>
18 #define for0(i,n) for(int i=0;i<=(n);i++)
19 #define for1(i,n) for(int i=1;i<=(n);i++)
20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
22 #define mod 1000000007
23 using namespace std;
24 inline int read()
25 {
26     int x=0,f=1;char ch=getchar();
27     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
28     while(ch>=‘0‘&&ch<=‘9‘){x=10*x+ch-‘0‘;ch=getchar();}
29     return x*f;
30 }
31 int n,s[maxn],q[maxn],wide[maxn],h[maxn];
32 int main()
33 {
34     freopen("input.txt","r",stdin);
35     freopen("output.txt","w",stdout);
36     n=read();
37     for1(i,n)s[i]=s[i-1]+read();
38     int l=0,r=0;q[0]=n+1;
39     for3(i,n,1)
40     {
41         while(l<r&&wide[q[l+1]]<=s[q[l+1]-1]-s[i-1])l++;
42         wide[i]=s[q[l]-1]-s[i-1];
43         h[i]=h[q[l]]+1;
44         while(l<r&&wide[i]-s[i-1]<wide[q[r]]-s[q[r]-1])r--;
45         q[++r]=i;
46     }
47     printf("%d\n",h[1]);
48     return 0;
49 }

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int a[100010],d[100010],s[100010],f[100010],q[100010],n,i,j,l,r;
 5 int main()
 6 {
 7     cin>>n;
 8     for(i=n;i;i--) scanf("%d",&a[i]);
 9     for(i=1;i<=n;i++) s[i]=s[i-1]+a[i];
10     l=1;
11     for(i=1,j=0;i<=n;i++)
12     {
13         while(l<=r&&s[i]-s[q[l]]>=f[q[l]]) j=q[l++];
14         f[i]=s[i]-s[j];
15         d[i]=d[j]+1;
16         while(l<=r&&f[i]<=f[q[r]]-s[i]+s[q[r]]) r--;
17         q[++r]=i;
18     }
19     cout<<d[n]<<endl;
20     return 0;
21 }

时间: 2024-10-11 08:46:27

BZOJ1233: [Usaco2009Open]干草堆tower的相关文章

bzoj1233: [Usaco2009Open]干草堆tower 单调队列优化dp

又是一道单调队列优化dp的题目 这道题呢 先要了解一个结论,在多种可行的堆叠方案中,至少有一种能使层数最高的方案同时使得底边最短.即底边最短的,层数一定最高. 这个是zkw大神得出的 我也不会证明来着 反正这样之后我们就可以得出正确的方法了 递推式 F[i]=min(sum[j-1]-sum[i-1])  j>i 且 sum[j-1]-sum[i-1]>=F[j] 易得在满足的条件下j当然是越小越好了嘛 而这样得出的方程又满足一定的单调性 这样调整之后队首就是我们要的答案啦 又对于转移条件 f

bzoj 1233: [Usaco2009Open]干草堆tower

1233: [Usaco2009Open]干草堆tower Description 奶牛们讨厌黑暗. 为了调整牛棚顶的电灯的亮度,Bessie必须建一座干草堆使得她能够爬上去够到灯泡 .一共有N大包的干草(1<=N<=100000)(从1到N编号)依靠传送带连续的传输进牛棚来.第i包干草有一个 宽度W_i(1<=w_i<=10000).所有的干草包的厚度和高度都为1. Bessie必须利用所有N包干草来建立起干草堆,并且按照他们进牛棚的顺序摆放.她可以相放多少包就放 多少包来建立起

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

首先这题的n^3的DP是比较好想的 f[i][j]表示用前i包干草 且最顶层为第j+1包到第i包 所能达到的最大高度 然而数据范围还是太大了 因此我们需要去想一想有没有什么单调性 ---------------------------------------------------------------------------------------------------- 从其他人的题解中 可以看到一个结论 我们尽量使底层最短 便可逐渐达到最优解 然后再结合递推的思想去做 我们就会使在底层

P1233: [Usaco2009Open]干草堆tower

这道题,首先想到的就两个,一是贪心,二是动规,然而 1<=N<=100000;1<=w_i<=10000 的数据范围实在不敢恭维,所以说第一想法是错的.仔细一想,首先,我们需要的是前一层的宽度大于等于下一层,高度(厚度)都是1,而宽度就是连续几个稻草块的宽度和,所以我们想到的方法就是 分段 使每一段稻草块的宽度和递减,并且使段数最多,而要使段数最多,则第一段就要越少(设总宽度 W , Wi>=Wj ,因此最少 W/W1 段),最后得出的段数就是高度了,那么这道题应该就化解了.

●BZOJ 1233 [Usaco2009Open] 干草堆 tower

题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1233 留坑.以后再来看看. (绝望,无奈,丧心...) (这个题的证明真的很诡异啊,看得我稀里糊涂的.) 原文地址:https://www.cnblogs.com/zj75211/p/8168879.html

bzoj1233 干草堆 - 单调队列优化dp

问题描述: 若有干个干草, 分别有各自的宽度, 要求将它们按顺序摆放, 并且每层的宽度不大于 它的下面一层 ,  求最多叠几层 题解: zkw神牛证明了: 底边最短, 层数最高         证明:传送门 接下来我们就可以根据这个结论进行dp. 前缀和sum, 以及 F[ i ]第 i 个数之后的干草叠起来后, 底层的最短宽度, 以及 H[ i ] 表示 第i个后的干草堆最高叠几层 有转移方程 : F[ i ] = min( sum[ j - 1] - sum[i - 1] ) ( j > i

USACO 2009 Open 干草塔 Tower of Hay(贪心+单调队列优化DP)

https://ac.nowcoder.com/acm/contest/1072/B Description 为了调整电灯亮度,贝西要用干草包堆出一座塔,然后爬到牛棚顶去把灯泡换掉.干草包会从传送带上运来,共会出现N包干草,第i包干草的宽度是Wi,高度和长度统一为1.干草塔要从底层开始铺建.贝西会选择最先送来的若干包干草,堆在地上作为第一层,然后再把紧接着送来的几包干草包放在第二层,再铺建第三层……重复这个过程,一直到所有的干草全部用完.每层的干草包必须紧靠在一起,不出现缝隙,而且为了建筑稳定,

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

bzoj usaco 金组水题题解(1)

UPD:我真不是想骗访问量TAT..一开始没注意总长度写着写着网页崩了王仓(其实中午的时候就时常开始卡了= =)....损失了2h(幸好长一点的都单独开了一篇)....吓得赶紧分成两坨....TAT.............. —————————————————————————————————————————————————————————————————————————————— 写(被虐)了整整一个月b站上usaco的金组题...然而到现在总共只写了100道上下TAT(当然是按AC人数降序排