在乙個圓形操場的四周擺放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 ...