石子合併動態規劃

2022-07-28 21:54:28 字數 1463 閱讀 6992

在乙個園形操場的四周擺放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 #include2

const

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次合併,...

動態規劃之合併石子

首先我們要搞懂什麼是動態規劃。我覺得動態規劃就是把乙個大問題分解為多個小問題,每個小問題的決策都會影響到下乙個小問題的決策。下乙個小問題的決策就是由上乙個小問題的決策而產生的。乙個狀態經過乙個決策變成了另外乙個狀態,這個過程就是狀態轉移,用來描述狀態轉移的方程就是狀態轉移方程。在乙個操場上一排地擺放...