在乙個園形操場的四周擺放n堆石子(n≤100),現要將石子有次序地合併成一堆。規定每次只能選相鄰的兩堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。
編一程式,由檔案讀入堆數n及每堆的石子數(≤20),
① 選擇一種合併石子的方案,使得做n-1次合併,得分的總和最小;
② 選擇一種合併石子的方案,使得做n-1次合併,得分的總和最大。
例如,所示的4堆石子,每堆石子數(從最上面的一堆數起,順時針數)依次為4 5 9 4。則3次合併得分總和最小的方案:8+13+22=43得分最大的方案為:22+18+22=54
解題思路:
根據題意來擬定狀態,dp[i][j]從i到j堆石子合併所得總分最大或者最小。
利用分治的思想我們就可以看得出來,我們首先將每相鄰的兩堆石子合併得到乙個得分,然後再擴充套件到3堆石子合併,3堆由兩堆石子的合併情況推出,這樣便形成了一種遞推的效果,n堆自然能夠推斷到,只是注意,本題是圍繞操場所以最後的石子與起始石子相鄰。
view code
1 #include2const
int n = 102;3
using
namespace
std;
4int sum[n*2][n*2],tt[n*2][n*2
],n;
5int
main()619
}20for(int i=1;i<2*n;i++)
21for(int j=1;j<2*n;j++)
22if(i==j)
23 tt[i][j]=0;24
else
25 tt[i][j]=100000000;26
for(int i=2;i<=n;i++)
27for(int j=1;j<2*n-i+1;j++)
2833}34
int mi=0x7fffffff;35
for(int i=1;i<=n;i++)
36if(tt[i][i+n-1]1
];37 printf("
%d\n
",mi);
38 memset(tt,0,sizeof
(tt));
39for(int i=2;i<=n;i++)
40for(int j=1;j<2*n-i+1;j++)
4146
}47 mi=0;48
for(int i=1;i<=n;i++)
49if(tt[i][i+n-1]>mi)mi=tt[i][i+n-1
];50 printf("
%d\n
",mi);51}
52return
0;
53 }
動態規劃 石子合併
題目描述 在乙個圓形操場的四周擺放n堆石子,現要將石子有次序地合併成一堆.規定每次只能選相鄰的2堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。試設計出1個演算法,計算出將n堆石子合併成1堆的最小得分和最大得分.輸入輸出格式 輸入格式 資料的第1行試正整數n,1 n 100,表示有n堆石...
石子合併 動態規劃(環形)
1 問題描述 問題 nwpu noj 1148 在乙個圓形操場的四周擺放著n堆石子 n 100 現要將石子有次序地合併成一堆。規定每次只能選取相鄰的兩堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。編一程式,讀入石子堆數n及每堆的石子數 20 選擇一種合併石子的方案,使得做n 1次合併,...
動態規劃之合併石子
首先我們要搞懂什麼是動態規劃。我覺得動態規劃就是把乙個大問題分解為多個小問題,每個小問題的決策都會影響到下乙個小問題的決策。下乙個小問題的決策就是由上乙個小問題的決策而產生的。乙個狀態經過乙個決策變成了另外乙個狀態,這個過程就是狀態轉移,用來描述狀態轉移的方程就是狀態轉移方程。在乙個操場上一排地擺放...