題意:
給出 n 個矩陣(a1,a2,…,an),求完全括號化方案,使得計算乘積(a1a2…an)所需乘法次數最少。並輸出方案。
思路:經典區間dp。
要求的是【0,n-1】的最小代價。且大區間的決策依賴於小區間。矩陣連乘的最後一定有乙個最後一次乘法,假設最後乙個乘號在第 k 個矩陣後,也就是p = a1 x a2 x … ak 和q = a(k+1) x a(k+2) x … x a(n)。只需分別求出p,q的最優方案(最優子結構)。為了計算p的最優方案,需要繼續列舉p = a1 x a2 x … ak的最後一次乘法,把它分成兩部分。由此發現,這個問題的子問題都是「把ai,a(i+1),,aj」乘起來需要多少次乘法。定義狀態:d[ i ][ j ]:從第 i 個矩陣連續乘到第 j 個矩陣的最小乘法次數。
轉移方程為:d[ i ][ j ] = min( d[ i ][ k ] + d[ k+1 ][ j ] + 最後一次乘法的代價 ).
記憶化搜尋:
int f(int i, int j)
} return ans;
}
遞推:
for(int len = 1; len <= n; ++len)
} }
完整**:
#include #include #include using namespace std;
const int inf = 0x3f3f3f3f;
const int n = 20;
int d[n][n], p[n], q[n], mark[n][n];
void print_ans(int i, int j)
printf("(");
print_ans(i, mark[i][j]);
printf(" x ");
print_ans(mark[i][j]+1, j);
printf(")");
}int f(int i, int j)
} return ans;
}int main()
// 遞推
for(int len = 1; len <= n; ++len)
} }
//int ans = f(0,n-1);
//printf("%d\n",ans);
printf("case %d: ",kase++);
print_ans(0,n-1);
printf("\n");
} return 0;
}
最優矩陣鏈乘
問題描述 乙個n m矩陣由n行m列共n m個數排列而成。兩個矩陣a和b可以相乘當且僅當a的列數等於b的行數。乙個n m的矩陣乘以乙個m p的矩陣等於乙個n p的矩陣,運算量為nmp。矩陣乘法滿足結合律,a b c可以表示成 a b c或者是a b c 兩者的運算量卻不同。例如當a 2 3 b 3 4...
最優矩陣鏈乘
題目大意 乙個n m矩陣由n行m列共n m個數排列而成。兩個矩陣a和b可以相乘當且僅當a的列數等於b的行數。乙個n m的矩陣乘以乙個m p的矩陣等於乙個n p的矩陣,運算量為nmp。矩陣乘法滿足結合律,a b c可以表示成 a b c或者是a b c 兩者的運算量卻不同。例如當a 2 3 b 3 4...
最優矩陣鏈乘
我們都學過矩陣的乘法。矩陣的乘法不滿足分配率,但是滿足結合律,因此矩陣 a b c 和 a b c 的結果是一樣的,但是中間的運算量可能是不同的。比如三個矩陣 a 2 times3 b 3 times4 c 4 times5 則 a times b times c 需要運算 2 times3 tim...