ADLSI : 連鎖行列積

参考:アルゴリズムイントロダクション15章 動的計画法
コード中のコメントはここに書いてあることです.
勘違いしてるかもしれません.

ソースコード

/*
	連鎖行列積問題
	
	演算結果はカッコ付けの順序にはよらないが、計算量(乗算回数)はカッコ付けの順番に依存する
		ー>乗算回数を最小にするカッコ付けを決定する
		 
	P(n) : n個の行列に対するカッコ付けの個数

	P(n) = 1 (n = 1)
	P(n) = \sum_{k = 1}^{n - 1} P(k) * P(n - k) (n >= 2)

	Ω(4^n/n^{3/2}) 

	問題の最適解に部分問題の最適解が含まれる
		ー>部分問題最適性

	m[i][j] = A_i, A_jの計算に必要なスカラ乗算の最小回数 (A_n : 行列)

	最適解はA_kとA_k+1で分割すると仮定する

	m[i][j] = 0 (i = j)
	m[i][j] = m[i][k] + m[k + 1][j] + p[i].first * p[k].second * p[j].second(i ≠ j)
*/

const int INF = 1 << 29;

int main()
{
	int n;
	scanf("%d", &n);

	int left[100], right[100];
	int m[100][100];

	for(int i = 0; i < n; i++)
		for(int j = 0; j < n; j++)
			m[i][j] = INF;

	for(int i = 0; i < n; i++)
	{
		scanf("%d%d", left + i, right + i);
		m[i][i] = 0;
	}

	for(int l = 1; l < n; l++)
	{
		for(int i = 0; i < n - l; i++)
		{
			int j = i + l;
			for(int k = i; k < j; k++)
			{
				m[i][j] = min(m[i][j], m[i][k] + m[k + 1][j] + left[i] * right[k] * right[j]);
			}
		}
	}

	printf("%d\n", m[0][n - 1]);	
}