詳解動態規劃石子合併問題 直線型, 環形

2021-09-16 20:27:25 字數 1543 閱讀 3551

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

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

輸入輸出格式

輸入格式:

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

輸入示例

44 4 5 9

輸出示例

4354

動態規劃

-則求dp[ i ][ n ]的最小解,1<=i<=n;

可以把dp[ i ][ n ]看成一堆,這一堆的最優解是由 由這堆分割的兩小堆合併的。 然後每兩小堆又可以再分,知道分成兩堆的石子合併,前面這部分是分治法的思想, 但是值得注意的是選擇不同的堆作為第一堆,得到的結果不一樣,這樣如果每個每種情況都像這樣分,就會有很多重複的,以致時間複雜度達到指數級, 所以我們要想辦法吧子問題的結果保留下來, 然後再得到最優解.這就是動態規劃的思想. 最普遍的做法是自底向上將子問題的儲存在陣列中.

#include

#include

#define ma_x 99999

#define mi_x 0

#define min

(a,b) a#define max

(a,b) a>b?a:b

int n,w[

200]

,dp[

200]

[200

],dq[

200]

[200];

//n表示堆數,w表示每隊的數量,dp[i][j]表示從第i堆開始合併j堆(包括第i堆)後的最小花費 ,dq表示最大

int sum

(int i,int t)

return s;

}int main()

//動態規劃

for(t=

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

} int mini=ma_x;

int maxi=mi_x;

for(i=

1;i<=n;i++

)printf

("%d "

,mini)

;printf

("%d "

,maxi)

;}

直線型合併的和環形合併,區別有兩點:

#include 

#include

#include

#define min

(a,b) aint a[

50005];

int dp[

505]

[505];

int sum[

505]

;int main()

for(int l=

1; l<=n-

1; l++

)//l是合併的次數}}

printf

("%d\n"

,dp[1]

[n])

;return0;

}

動態規劃思想 石子合併問題

描述 在乙個圓形操場的四周擺放著n 堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2 堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。試設計乙個演算法,計算出將n堆石子合併成一堆的最小得分和最大得分。開始以為通過貪心演算法可能很快解決問題,可是是行不通的。首先我們可以把這麼堆...

動態規劃 石子合併

題目描述 在乙個圓形操場的四周擺放n堆石子,現要將石子有次序地合併成一堆.規定每次只能選相鄰的2堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。試設計出1個演算法,計算出將n堆石子合併成1堆的最小得分和最大得分.輸入輸出格式 輸入格式 資料的第1行試正整數n,1 n 100,表示有n堆石...

石子合併動態規劃

在乙個園形操場的四周擺放n堆石子 n 100 現要將石子有次序地合併成一堆。規定每次只能選相鄰的兩堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。編一程式,由檔案讀入堆數n及每堆的石子數 20 選擇一種合併石子的方案,使得做n 1次合併,得分的總和最小 選擇一種合併石子的方案,使得做n ...