【動的計画法】連鎖行列積
動的計画法の例題です。連鎖行列積をやります。アルゴリズムの勉強と実装をします。
連鎖行列積
厳しい名前がついていますが、やることは行列の積の計算順序の決定です。 与えられたn個の行列の連鎖の積を計算しますが、計算結果には興味がありません。見つけたいのは、計算回数を最小にする積の順序です。
行列と行列の積では、回が計算が生じます。
例えば、が与えられたとき、 とのどちらが計算量が少ないか、ということです。
アルゴリズム
を行列とします。の計算回数はとなります。 計算回数をコストと呼ぶことにすると、上の例では、
ここで、
当然、についてが成り立ちます。 これを一般化すると、
となります。ただし、の最小コストをと書いています。
実装
次の問題を解いてみました。
連鎖行列積 | アルゴリズムとデータ構造 | Aizu Online Judge
ループの範囲に注意します。
解答例:
#include<iostream> using namespace std; #define N 100 int main() { int i, j, k, l, n, p[N+1], cost[N+1][N+1], min_cost; cin >> n; for (i = 1; i <= n; i++) cin >> p[i-1] >> p[i]; // 初期値 for (i = 1; i <= n; i++) cost[i][i] = 0; for (l = 2; l <= n; l++) { // 行列の個数 for (i = 1; i <= n - l + 1; i++) { j = i + l - 1; for (k = i; k < j; k++) { if (k == i) min_cost = cost[i][k] + cost[k+1][j] + p[i-1] * p[k] * p[j]; else min_cost = min(min_cost, cost[i][k] + cost[k+1][j] + p[i-1] * p[k] * p[j]); } cost[i][j] = min_cost; } } cout << cost[1][n] << endl; return 0; }
参考
渡部有隆. プログラミングコンテスト攻略のためのアルゴリズムとデータ構造. Ozy, 秋葉拓哉協力. 株式会社マイナビ. 2015.