石子合併(三) 環形合併

2021-07-31 05:19:04 字數 1258 閱讀 3883

題目描述

在乙個園形操場的四周擺放n堆石子,現要將石子有次序地合併成一堆.規定每次只能選相鄰的2堆合併成新的一堆,合併的花費為這相鄰兩堆之和

試設計出1個演算法,計算出將n堆石子合併成1堆的最小花費.

輸入輸出格式

輸入格式:

資料的第1行試正整數n,1≤n≤100,表示有n堆石子.第2行有n個數,分別表示每堆石子的個數.

輸出格式:

輸出最小得分

題解:

動態規劃

dp[i][t]=min(dp[i][t],dp[i][k]+dp[(i+k-1)%n+1][t-k]+sum(i,t))

dp[ i ][ t ]表示從 i開始之後t堆石子合併花費。 則求dp[ i ][ n ]的最小解,1<=i<=n;

可以把dp[ i ][ n ]看成一堆,這一堆的最優解是由 由這堆分割的兩小堆合併的。

這兩小堆分別是多大才才能得到最優解,要列舉。 在列舉的過程中將各個值儲存起來,就是動態規劃。

例如4堆過程:

初始化 dp[i][1]=0 ;此時還沒有合併,沒有花費

第一次合併得:dp[ 1 ][ 2 ],dp[ 2 ][ 2 ],dp[ 3 ][ 2 ],dp[ 4 ][ 2 ],及12,23,34,41;

第二次合併得:dp[ 1 ][ 3 ],dp[ 2 ][ 3 ],dp[ 3 ][ 3 ],dp[ 4 ][ 3 ],及123,234,341,412;

第三次合併得:dp[ 1 ][ 4 ],dp[ 2 ][ 4],dp[ 3 ][ 4 ],dp[ 4 ][ 4 ],及1234,2345,3412,4123;

合併過程中用dp[i][t]=min(dp[i][t],dp[i][k]+dp[(i+k-1)%n+1][t-k]+sum(i,t))求值

#include

#include

#define ma_x 99999

#define min(a,b) aint n,w[205],dp[205][205];

int sum(int i,int t)

return s;

}int main()

//核心演算法,動態規劃

for(t=2;t<=n;t++)}}

int mini=ma_x;

for(i=1;i<=n;i++)

printf("%d ",mini);

}

1148環形石子合併

時限 1000ms 記憶體限制 10000k 總時限 3000ms 描述在乙個圓形操場的四周擺放著n堆石子 n 100 現要將石子有次序地合併成一堆。規定每次只能選取相鄰的兩堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。編一程式,讀入石子堆數n及每堆的石子數 20 選擇一種合併石子的方...

ACWing 1068 環形石子合併

將n nn堆石子繞圓形操場排放,現要將石子有序地合併成一堆。規定每次只能選相鄰的兩堆合併成新的一堆,並將新的一堆的石子數記做該次合併的得分。請編寫乙個程式,讀入堆數n nn及每堆的石子數,並進行如下計算 選擇一種合併石子的方案,使得做n 1 n 1n 1次合併得分總和最大。選擇一種合併石子的方案,使...

NC50493 環形石子合併

狀態表示 f i,j 從下標 i 合併到下標 j 的最大價值。先看石子合併 n 堆石子 1,2,n f 1,n 即為答案。再看環形 最後的答案為 f 1,n f n,1 和f 1,n 結果相同 f 2,1 f 3,2 中的最小值。我們當然不能在環上直接 dp 因為這樣 f 2,1 f 3,2 的合併...