動態規劃專題之石子合併

2021-08-21 01:25:07 字數 2774 閱讀 2041

動態規劃專題講義

專題九:合併石子問題

/* 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 ...