有N个矩阵,分别是A1*A2, A2*A3, A3*A4, etc.....
求连乘的最小结果。
动态规划,其实也可以称作分解法,因为不知道在i --> j 中間哪裡斷開,所以要求所有值,然後更新到最小。
下面的代碼中,fix()是從recursive角度來解決的,效率不高,但是思想是動態規劃的。
fix2()是對fix的優化,降低時間複雜度,這個 一般對遞歸都是這麼的二維數組處理。
fix2中的r 是表示dp[i][j]的長度,比如A1-A2就是2, 然後求所有的len為2的A3-A4,A4-A5 etc
dp[i][j] 是存儲的i到j的最小值,最後i=1,j=len-1 就是我們要的結果
#include <iostream>
#include <queue>
#include <string>
#include <memory>
#include <algorithm>
#include <map>
using namespace std;
#define N 100
int A[7]={30,35,15,5,10,20,25};
int dp[N][N];
/*
30 ---- 35 ---- 15 ---- 5---- 10 ---- 20 ---- 25
lh lh+1 rh
*/
int fix(int lh, int rh){
//lh in func fix() begin with p[1]
if(lh==rh) return 0;
int res=fix(lh,lh)+fix(lh+1,rh)+A[lh-1]*A[lh]*A[rh];
for(int k=lh+1;k<rh;k++){
int tmp = fix(lh,k)+fix(k+1,rh)+A[lh-1]*A[k]*A[rh];
if(tmp<res) res=tmp;
}
return res;
}
int fix2(int len){
//fix2 is not recursive, lh/rh not needed
for(int i=1;i<=len;i++) dp[i][i]=0; //init 0
for(int r=2;r<=len;r++){
for(int i=1;i<=len-r+1;i++){
int j=i+r-1;
dp[i][j]=dp[i][i]+dp[i+1][j]+A[i-1]*A[i]*A[j];
for(int k=i+1;k<j;k++){
int tmp=dp[i][k]+dp[k+1][j]+A[i-1]*A[k]*A[j];
if(dp[i][j]>tmp) dp[i][j]=tmp;
}
}
}
return dp[1][len-1];
}
int main(void){
//freopen("input.txt","r",stdin);
cout<<fix(1,6)<<endl;
cout<<fix2(7)<<endl;
//cout<<dp[1][4]<<endl;
return 0;
}