石子合併問題

2021-06-01 01:45:37 字數 917 閱讀 4891

**:

在乙個圓形操場的四周擺放著n堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。試設計乙個演算法,計算出將n堆石子合併成一堆的最小得分和最大得分。

分析:假設有n堆石子需要合併,可以設計乙個2*n-1個元素的陣列來儲存每堆石子的個數。

分析最優解的結構:假設有石頭aiai+1……aj需要合併,簡記為a[i,j].如果設最後一次合併發生在ak與ak+1之間(i<=k

證明:

假設存在乙個比計算a[0,k]的次序得分更少的次序,則用此次序來替換原來計算a[0,k]的次序,那麼此時計算a[0,n-1]次序的得分就會比最優次序所得到的分數更少,這與假設相矛盾;同理可證明:計算a[0,n-1]的乙個最優次序所包含的另乙個計算子鏈a[k+1,n-1]的次序也是最優的!

綜上所述,此題滿足最優子結構性質,因此可以用動態規劃演算法來求解.

建立遞迴關係

設m[i][j]表示a[i,j]的計算結果.

當i=j時,表示只有一堆石頭,不能合併,因此得分為零,所以m[i,j]=0; 當i

void matrixchain(int *p,int n,int **m,int flag) //矩陣連乘演算法}}

matrixchain(inputnum,2*n-1,m,0); //計算最小得分

int resultmin=m[0][n-1];

for(i=1;i<=n-1;i++)

if(resultmin>m[i][n-1+i])

resultmin=m[i][n-1+i];

matrixchain(inputnum,2*n-1,m,1); //計算最大得分

int resultmax=m[0][n-1];

for(i=1;i<=n-1;i++)

if(resultmax

石子合併問題

在乙個圓形操場的四周擺放著n堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。試設計乙個演算法,計算出將n堆石子合併成一堆的最小得分和最大得分。沒有用dp 感覺一般的也能寫,時間複雜度也不高。include include inc...

石子合併問題

石子合併問題是最經典的dp問題。首先它有如下3種題型 1 有n堆石子,現要將石子有序的合併成一堆,規定如下 每次只能移動任意的2堆石子合併,合併花費為新合成的一堆石子的數量。求將這n堆石子合併成一堆的總花費最小 或最大 分析 當然這種情況是最簡單的情況,合併的是任意兩堆,直接貪心即可,每次選擇最小的...

石子合併問題

原文 石子合併問題是最經典的dp問題。首先它有如下3種題型 1 有n堆石子,現要將石子有序的合併成一堆,規定如下 每次只能移動任意的2堆石子合併,合併花費為新合成的一堆石子的數量。求將這n堆石子合併成一堆的總花費最小 或最大 分析 當然這種情況是最簡單的情況,合併的是任意兩堆,直接貪心即可,每次選擇...