2298 石子合併

2022-04-07 02:00:01 字數 1751 閱讀 1396

2023年省隊選拔賽山東

時間限制: 1 s

空間限制: 256000 kb

題目等級 : ** gold

在乙個操場上擺放著一排n堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。

試設計乙個演算法,計算出將n堆石子合併成一堆的最小得分。

輸入描述 input description

第一行是乙個數n。

以下n行每行乙個數a,表示石子數目。

輸出描述 output description

共乙個數,即n堆石子合併成一堆的最小得分。

樣例輸入 sample input

樣例輸出 sample output

資料範圍及提示 data size & hint

對於 30% 的資料,1≤n≤100

對於 60% 的資料,1≤n≤1000

對於 100% 的資料,1≤n≤40000

對於 100% 的資料,1≤a≤200

思路:原來是想用區間dp,但資料太大。就這樣了。。。

(1). 假設我們只對3堆石子a,b,c進行比較, 先合併哪2堆, 使得得分最小.

score1 = (a+b) + ( (a+b)+c )

score2 = (b+c) + ( (b+c)+a )

再次加上score1 <= score2, 化簡得: a <= c, 可以得出只要a和c的關係確定,

合併的順序也確定.

(2). garsiawachs演算法, 就是基於(1)的結論實現.找出序列中滿足stone[i-1] <=

stone[i+1]最小的i, 合併temp = stone[i]+stone[i-1], 接著往前面找是否

有滿足stone[j] > temp, 把temp值插入stone[j]的後面(陣列的右邊). 迴圈

這個過程一直到只剩下一堆石子結束.

(3). 為什麼要將temp插入stone[j]的後面, 可以理解為(1)的情況

從stone[j+1]到stone[i-2]看成乙個整體 stone[mid],現在stone[j],

stone[mid], temp(stone[i-1]+stone[i-1]), 情況因為temp < stone[j],

因此不管怎樣都是stone[mid]和temp先合併, 所以講temp值插入stone[j]

的後面是不影響結果.

1 #include2

3const

int n = 50010; 4

5int

a[n];

6int n,t=1;7

long

long

ans;89

void work(int

k)10

17 t--;

18int j = 0;19

for(j=k-1;j>0 && a[j-1]//

往前面找

2023 a[j] =tmp;

24while(j>=2 && a[j]>=a[j-2

])2530}

31int

main()

3238

for(int i=1;i//

注意限制條件

3943

while(t>1) work(t-1

);44 printf("

%lld

",ans);

45return0;

46 }

282 石子合併

設有n堆石子排成一排,其編號為1,2,3,n。每堆石子有一定的質量,可以用乙個整數來描述,現在要將這n堆石子合併成為一堆。每次只能合併相鄰的兩堆,合併的代價為這兩堆石子的質量之和,合併後與這兩堆石子相鄰的石子將和新堆相鄰,合併時由於選擇的順序不同,合併的總代價也不相同。例如有4堆石子分別為 1 3 ...

2298 石子合併 2023年省隊選拔賽山東

題目描述 description 在乙個操場上擺放著一排n堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。試設計乙個演算法,計算出將n堆石子合併成一堆的最小得分。輸入描述 input description 第一行是乙個數n。以...

3 3 石子合併問題

問題描述 在乙個圓形操場的四周擺放著 n 堆石子。現要將石子有次序地合併成一堆。規定每次只 能選相鄰的 2 堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。試設計一 個演算法,計算出將 n 堆石子合併成一堆的最小得分和最大得分。程式設計任務 對於給定 n 堆石子,程式設計計算合併成一堆的...