bzoj 1233 or 3549

题目背景

为了调整电灯亮度,贝西要用干草包堆出一座塔,然后爬到牛棚顶去把灯泡换掉。干草包会从传送带上运来,共会出现N包干草,第i包干草的宽度是W i ,高度和长度统一为1。干草塔要从底层开始铺建。贝西会选择最先送来的若干包干草,堆在地上作为第一层,然后再把紧接着送来的几包干草包放在第二层, 再铺建第三层……重复这个过程, 一直到所有的干 草全部用完。每层的干草包必须紧靠在一起,不出现缝隙,而且为了建筑稳定,上层干草的宽度不能超过下层的宽度。 按顺序运来的干草包一定要都用上, 不能将其中几个干草包弃置不用。贝西的目标是建一座最高的塔,请你来帮助她完成这个任务吧。

题目描述

输入输出格式

输入格式:

 

第一行:单个整数:NN,1 ≤ N ≤ 1000001N100000 第二行到N + 1N+1行:第i + 1i+1行有一个整数W_iWi ,1 ≤ W_i ≤ 100001Wi10000

 

输出格式:

 

第一行:单个整数,表示可以建立的最高高度

 

输入输出样例

输入样例#1: 复制
3
1
2
3
输出样例#1: 复制
2

说明

将 1 和 2 放在第一层,将 3 放在第二层

 

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define re register
 4 #define R  re int
 5 #define rep(i,a,b) for(R i=a;i<=b;i++)
 6 #define Rep(i,a,b) for(R i=a;i>=b;i--)
 7 template<class T>inline void read(T &x){
 8   x=0; char c=0;
 9   while (!isdigit(c)) c=getchar();
10   while (isdigit(c)) x=x*10+(c^48),c=getchar();
11 }
12 int const N=100000+3;
13 int n,a[N],q[N],s[N],f[N],g[N];
14 int main(){
15   read(n);
16   rep(i,1,n){
17     read(a[i]);s[i]=s[i-1]+a[i];
18   }
19   int l=0,r=0; q[0]=n+1;
20   Rep(i,n,1){
21     while (l<r && s[q[l+1]-1]-f[q[l+1]]>=s[i-1]) l++;
22     f[i]=s[q[l]-1]-s[i-1];
23     g[i]=g[q[l]]+1;
24     while (l<=r && s[i-1]-f[i]>=s[q[r]-1]-f[q[r]]) r--;
25     q[++r]=i;
26   }
27   printf("%d\n",g[1]);
28   return 0;
29 }
View Code

 

posted @ 2018-12-29 16:36  zjxxcn  阅读(209)  评论(0编辑  收藏  举报