動態規劃之矩陣練乘加括號問題
阿新 • • 發佈:2019-02-05
/*
因為相乘順序會影響標量的乘法大小,所以加括號的位置非常影響乘法結果的大小
*/
#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 <<")";
}
}