石子合併(區間型動規)

2021-07-15 13:21:38 字數 2918 閱讀 8563

在乙個圓形操場的四周擺放n堆石子(n≤500),現要將石子有次序地合併成一堆。規定每次只能選相鄰的兩堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。

編一程式,由檔案讀入堆數n及每堆的石子數;

⑴ 選擇一種合併石子的方案,使得做n-1次合併,得分的總和最小;

⑵ 選擇一種合併石子的方案,使得做n-1次合併,得分的總和最大。

輸入檔案:

第1行為n,代表n堆石子;

第2行為n個數,代表每堆石子的數量。

輸出檔案:

第1行為合併的得分總和最小值;

第2行為合併的得分總和最大值。

輸入樣例:

4

4 5 9 4(從最上面的一堆數起,順時針數)

輸出樣例:

43(最小)

54(最大)

【分析】

6堆石子合併的最小得分方案min是由merge(①,②,③)+merge(④,⑤,⑥)得來的,上述中,merge表示合併。merge(①,②,③)時,它有兩種合併方案,即先merge(①,②)兩堆,再將①②合併的結果與第③堆合併,或先merge(②,③),再將②③合併的結果與第①堆合併。兩種方案的合併過程如下:

第一種合併方案:(3+4)+6合併得分為7+13=20;

第二種合併方案:3+(4+6)合併得分為10+13=23。

兩種方案相比,明顯第一種方案得分小。merge(④,⑤,⑥)時,同樣的,也有兩種方案,即先merge④,⑤兩堆,再將④⑤合併的結果與第⑥堆合併,或merge⑤,⑥,再將⑤⑥合併的結果與第④堆合併。兩種方案的合併過程如下:

第一種合併方案:(5+4)+2合併得分為9+11=20;

第二種合併方案:5+(4+2)合併得分為6+11=17。

這兩種方案相比,明顯第二種方案得分小。從圖2-2中的最小合併得分結果來看,在計算6堆石子合併的最小得分min時,它的計算過程明顯是取min和min的。由此可以初步看出,合併石子時具備最優子結構的性質。詳細看合併1到6堆時存在的過程。

合併1堆:①,②,…,⑥;

合併2堆:①②,②③,…,⑥①;

合併3堆:①②③,②③④,…,⑥①②;

合併4堆:①②③④,②③④⑤,…,⑥①②③;

合併5堆:①②③④⑤,②③④⑤⑥,…,⑥①②③④;

合併6堆:①②③④⑤⑥,②③④⑤⑥①,…,⑥①②③④⑤。

有合併過程可以看出,從第i堆開始合併j堆時,它的值可以為第i堆+min。如從第①堆開始合併4堆時,它可以為第①堆+min,可以為min+min,可以為min+第④堆,共有3種**,與區間的合併有關。以此類推,合併到6堆時,取從第i堆開始合併6堆的最小值,即得到合併的總的最小值。所以,我們可以肯定地說,此問題具備最優子結構的性質,而且無後效性。

用合併的堆數作階段,用f[i,j]作狀態,表示從第i堆數起,順時針合併j堆的總得分最小值,它包括合併前j-1堆的最小總得分加上這次合併的得分,用sum[i,j]表示這次合併的得分。合併時的堆數可以表示為序列。序列總得來的方案有很多種,我們用子串行1和子串行2表示,如子串行1為,則子串行2為。子串行1和子串行2相鄰,所以,假如子串行1為k堆,則子串行2為j-k堆。由此,可以得到動規方程:

f[i,j]=min

用stone[i]表示初始時每堆的石子數,則動規的初始條件為:

f[i,1]=0

動規的邊界為1≤i<n,1≤j≤n。求最大得分與最小得分方法一樣,只是在計算時反一下即可。本演算法的時間效率為o(n

3)

#include#include#include#define inf 65535

using namespace std;

int n;

int num[510];///每堆石頭數

int sum[510][510];

int fmin[510][510];///儲存最小

int fmax[510][510];///儲存最大

int main()

///預設好從第i 堆開始合併j堆石頭的當次得分

for(int j=2;j<=n;j++)

}///以合併的堆數為階段,做動態規劃

for(int j=2;j<=n;j++)///階段,即合併堆數}}

///依次判斷石頭的合併位置,求出最小,最大得分

int maxn=0;

int mint=inf;

for(int j=1;j<=n;j++)

printf("%d ",mint);

printf("%d",maxn);

return 0;

}

區間動規經典題 石子合併

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

區間動規經典題 石子合併

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

動規之 環形石子合併

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