BZOJ 3229 Sdoi2008 石子合併

2022-05-26 02:12:11 字數 1694 閱讀 7223

時間限制: 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 #include6

#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 }

view code

你以為這可以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開始,這些任務被分批加工...