1. 程式人生 > >BZOJ1233: [Usaco2009Open]幹草堆tower

BZOJ1233: [Usaco2009Open]幹草堆tower

ora content data 傳輸 -s math .org 說明 script

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 |
+---+------+
我的智商完全不兼容單調隊列的趕腳

設f[i]表示i~n組草堆底下最少的寬度,g[i]表示這個草堆的高度,sum[i]表示前綴和

f[i]=min(sum[j1]sum[i1])(f[j]<=sum[j1]sum[i1]) 然後n2隨便肏

化下柿子,sum[i1]<=sum[j1]f[j],證一下單調性 然後這道題很神。。。他是有限制的單調方程 又因為隊頭一定合法,我們就直接幹到最小值了
代碼如下:
//
MT_LI #include<cmath> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; typedef long long ll; ll f[210000],g[210000],s[210000],a[210000];//[i]表示i~n組草堆底下最少的寬度,g[i]表示這個草堆的高度,sum[i]表示前綴和 // f[i]=min(sum[j-1]-sum[i-1])(f[j]<=sum[j-1]-sum[i-1]) int n; int list[210000]; int head,tail; int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%lld",&a[i]),s[i]=s[i-1]+a[i]; head=1,tail=1;list[1]=n+1; for(int i=n;i>=1;i--) { while(head<tail&&s[list[head+1]-1]-s[i-1]>=f[list[head+1]])head++; int j=list[head]; g[i]=g[j]+1;f[i]=s[j-1]-s[i-1]; while(head<=tail&&s[list[tail]-1]-f[list[tail]]<=s[i-1]-f[i])tail--; list[++tail]=i; } printf("%lld\n",g[1]); return 0; }

BZOJ1233: [Usaco2009Open]幹草堆tower