時間限制: 3 sec 記憶體限制: 128 mb
提交: 497 解決: 240
[提交]
在乙個操場上擺放著一排n堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。
試設計乙個演算法,計算出將n堆石子合併成一堆的最小得分。
第一行是乙個數n。
以下n行每行乙個數a,表示石子數目。
共乙個數,即n堆石子合併成一堆的最小得分。41
1118
對於 100% 的資料,1≤n≤40000
對於 100% 的資料,1≤a≤200
接下來是嘴巴時間!!
po1:
顯然如果資料範圍變小這可是一道dp入門題:f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+sum(i,j)) (i,j表示的是區間[i,j]的最優解,i<=ko(n^3)!
po2:
為了降低複雜度
介紹四邊形優化
設s(i,j)為f[i][j]為最優解時k的值,假設我們已經知道四邊形優化是這樣的s(i,j-1)<=s(i,j)<=s(i+1,j)那麼在迴圈k的時候我們就只用從s(i,j-1)迴圈到(s+1,j)了,這是近乎於o(1)的。
o(n^2)!! 但是陣列無法滾動會卡掉空間qaq
po3:
garsiawachs!
這是專門用於解決石子合併類問題的演算法:乙個序列是a[0..n-1],每次尋找最小的乙個滿足a[k-1]<=a[k+1]的k,(方便起見設a[-1]和a[n]等於正無窮大)那麼我們就把a[k]與a[k-1]合併,之後找最大的乙個滿足a[j]>a[k]+a[k-1]的j,把合併後的值a[k]+a[k-1]插入a[j]的後面,反覆進行直到序列為1個數字。
栗子:186 64 35 32 103 (35<103)
186 67 64 103 (64<103)
186 131 103 (a[-1]和a[n]等於正無窮大)
234 186
420ans=420+234+131+67=852
o(n^2) 可以勉強過了這道題
po4:
在po3的基礎上splay維護此序列。
o(nlogn)
1 #include2 #include3 #include4 #include5 #include6view code#define yyj(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout);
7#define llg long long
8#define maxn 40010
9llg i,j,k,x,n,m,a[maxn],ans;
10using
namespace
std;
11 llg get
()12
1819
intmain()
2035 cout<
36return0;
37 }
你以為這可以a?這只是一發常數寫大了超時的
當你把常數寫小
1548112
xrdog
3229
正確1484 kb
60 ms
c++/edit
1080 b
2016-07-14 20:13:13
石子合併 BZOJ 3229
題目傳送門 題意 石子合併問題一般來說都是o n 3 的複雜度,如果用四邊形不等式優化的話可以使時間複雜度降低到o n 2 的複雜度,但是這個題目的資料範圍是40000,所以這個題要用到garsiawachs演算法,可以使時間複雜度降到o n logn 從而解決這個題目。include includ...
BZOJ3229 石子合併
description 在乙個操場上擺放著一排n堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。試設計乙個演算法,計算出將n堆石子合併成一堆的最小得分。input 第一行是乙個數n。以下n行每行乙個數a,表示石子數目。outpu...
Bzoj 2726 SDOI 任務安排
memory limit 131072kb 64bit io format lld llu description 機器上有n個需要處理的任務,它們構成了乙個序列。這些任務被標號為1到n,因此序列的排列為1,2,3.n。這n個任務被分成若干批,每批包含相鄰的若干任務。從時刻0開始,這些任務被分批加工...