1. 程式人生 > >動態規劃之矩陣練乘加括號問題

動態規劃之矩陣練乘加括號問題

/*
因為相乘順序會影響標量的乘法大小,所以加括號的位置非常影響乘法結果的大小
*/

#include<iostream>
using namespace std;
void matrix_chain_order(int *p,int m[][1000],int s[][1000],int n);
void print(int s[][1000],int i,int j);
int main()
{
    int p[1000];//儲存第一個行,和其他的列
    cout <<"請輸入要輸入矩陣的個數:";
    int num = 0 ;
    cin >> num;
    int
row = 0,column = 0; cout <<"請依次輸入矩陣的行和列:"; cin >> row >> column; //因為p[0]要存第一個矩陣的行,之後的p都是存矩陣的列 //這裡我剛開始也不懂,但是找了一個例子 //a1是30*35,a2是35*15,a3是15*15 //a1和a2乘積次數是30*35*15,之後再和a3是15*15 //總之只用到了第一個矩陣的行,其餘矩陣的列(包括第一個矩陣自己的列) p[0] = row,p[1] = column; for(int i = 2;i <= num;i++) { cin
>> row >> column; p[i] = column; } int m[1000][1000]={0};//儲存最少乘積次數 int s[1000][1000]={0};//儲存加括號的位置 matrix_chain_order(p,m,s,num); print(s,1,num); return 0; } void matrix_chain_order(int *p,int m[][1000],int s[][1000],int n) { for(int i = 0;i <= n;i++) m[i][i] = 0;//i=i,此時只有一個矩陣,所以不用算
for(int l = 2;l <= n;l++)//l是以有兩個鏈為開始 for(int i = 1;i <= n-l+1;i++)//有m[i,j]時j-i+1是整個矩陣鏈的長度,同時i也是左邊界 { int j = i+l-1;//這個是右邊界 m[i][j] = m[i][i] + m[i+1][j] + p[i-1]*p[i]*p[j]; s[i][j] = i; //演算法導論裡這裡寫的是m[i][j]無窮大,無窮大不好表示,所以感覺m提前用公式算出來,會好一點。 for(int k = i+1;k < j;k++)//k就是放括號的位置 { int tmp = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]; if(tmp < m[i][j]) { m[i][j] = tmp; s[i][j] = k; } } } } void print(int s[][1000],int i,int j) { if(i == j) cout << "A"<<i<<" "; else { cout <<"("; print(s,i,s[i][j]);//s[i][j]相當於k,所以分為兩個部分 print(s,s[i][j]+1,j); cout <<")"; } }