動態規劃專題講義
專題九:合併石子問題
/* name: 動態規劃專題之石子合併
author: 巧若拙
description:
在乙個操場上擺放著一排n堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。
試設計乙個演算法,計算出將n堆石子合併成一堆的最小得分。
輸入描述 input description
第一行是乙個數n。1≤n≤100
以下n行每行乙個數a,表示石子數目。1≤a≤200
輸出描述 output description
共乙個數,即n堆石子合併成一堆的最小得分。
樣例輸入 sample input
713 7 8 16 21 4 18
樣例輸出 sample output
239*/
#includeusing namespace std;
const int int_max = 2147483647;
const int max = 1000;
int a[max+1];//記錄每堆石子的數量
int sum[max+1];//記錄前n堆石子的數量
int b[max+1][max+1];//記錄第i堆石子至第j堆石子的最優解
int s[max+1][max+1];//記錄從**斷開的才可得到最優解
bool flag[max+1]; //記錄a[i]是否已經被輸出過
int stonescombined(int i, int j);//自頂向下,使用備忘錄陣列的動態規劃演算法
int stonescombined_2(int n);//自底向上的動態規劃演算法:遞增括號中石子堆數量
int stonescombined_3(int n);//自底向上的動態規劃演算法:逆序掃瞄
int stonescombined_4(int n);//自底向上的動態規劃演算法:順序掃瞄
void traceback(int i, int j);//根據s記錄的各個子段的最優解,將其輸出
int main()
// cout << stonescombined(1, n) << endl;//自頂向下,使用備忘錄陣列的動態規劃演算法
cout << stonescombined_2(n) << endl;//自底向上的動態規劃演算法
traceback(1, n);
cout << endl;
return 0;
}演算法1:自頂向下,使用備忘錄陣列的動態規劃演算法,需要用到全域性變數s[max+1], 另有b[max+1]初始化為0。
int stonescombined(int i, int j)
{ if (b[i][j] != 0)
return //語句1
if (i == j)
return //語句2
int t, m = int_max;
for (int k=i; k=2; len--) ?為什麼?
問題2:將語句2補充完整。
問題1:不能。len代表當前被合併在一起的石子堆的數量,演算法的思想是先計算所有相鄰的2堆石子合併在一起的解,再計算所有所有相鄰的3堆石子合併在一起的解,逐步擴大子問題的規模。在計算較大規模的問題時,可以呼叫較小規模子問題的解。所以len必須從小到大。
問題2:語句2:int j = i + len - 1; //右邊界
演算法3:自底向上的動態規劃演算法:逆序掃瞄,需要用到全域性變數s[max+1], 另有b[max+1]初始化為0。
int stonescombined_3(int n)
{ for (int i=n-1; i>0; i--)
{ for (int j=i+1; j<=n; j++)// 語句1
{int t, m = int_max;
for (int k=i; ki; j--)?為什麼?
問題2:語句2能否改為:for (int k=j-1; k>=i; k--)?為什麼?
問題1:不能。i和j分別代表當前被合併石子堆的左,右邊界,演算法3的基本思想是在確定左邊界的情況下,逐步擴大子問題的右邊界。在計算較大規模的問題時,可以呼叫較小規模子問題的解。所以j必須遞增。
問題2:可以。k代表分隔石子堆的位置(即把[i,k]和[k+1,j]兩堆石子合併成[i,j]一堆石子),只要滿足i<=k0; i--)// 語句1
{int t, m = int_max;
for (int k=i; k,要計算乘積a1a2.....an。一組矩陣是加全部括號的。
矩陣鏈加括號對運算的效能有很大影響。
僅當兩個矩陣a和b相容(即a的列數等於b的行數),才可以進行相乘運算。如果a是乙個p×q矩陣,b是q×r矩陣,結果c是p×r的矩陣。
計算c的時間由乘法運算次數決定的,次數為p×q×r。
矩陣鏈乘法問題可表述為:給定n個矩陣構成的乙個鏈,其中i=1,2,3,4.....,n,矩陣ai的維數為pi-1 ×pi,
對乘積a1a2a3.....an,以一種最小標量乘法次數的方式進行加全部括號。
輸入描述 input description
如果有n個陣列,則第一行輸入n+1個整數值
輸出描述 output description
所有的陣列以一種最小標量乘法次數的方式進行加全部括號。
樣例輸入 sample input
1 2 3 4
樣例輸出 sample output
((a1a2)a3)
動態規劃之合併石子
首先我們要搞懂什麼是動態規劃。我覺得動態規劃就是把乙個大問題分解為多個小問題,每個小問題的決策都會影響到下乙個小問題的決策。下乙個小問題的決策就是由上乙個小問題的決策而產生的。乙個狀態經過乙個決策變成了另外乙個狀態,這個過程就是狀態轉移,用來描述狀態轉移的方程就是狀態轉移方程。在乙個操場上一排地擺放...
動態規劃 石子合併
題目描述 在乙個圓形操場的四周擺放n堆石子,現要將石子有次序地合併成一堆.規定每次只能選相鄰的2堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。試設計出1個演算法,計算出將n堆石子合併成1堆的最小得分和最大得分.輸入輸出格式 輸入格式 資料的第1行試正整數n,1 n 100,表示有n堆石...
石子合併動態規劃
在乙個園形操場的四周擺放n堆石子 n 100 現要將石子有次序地合併成一堆。規定每次只能選相鄰的兩堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。編一程式,由檔案讀入堆數n及每堆的石子數 20 選擇一種合併石子的方案,使得做n 1次合併,得分的總和最小 選擇一種合併石子的方案,使得做n ...