#include <stdio.h>
#include <string.h>
/*
假设每对相邻矩阵都满足可乘条件 Col(mi) = Row(mj)
矩阵乘法左结合 第i个矩阵记作mi
子乘法计算因式记作A[i:j] i,j in range(1,n)
mi维度记作p[i-1]:p[i] plen = 2*n+1
对应的最少计算步记作m[i,j]
则还原答案为m[1,n]
*/
/*
最有子问题 i = j;
最优子答案 m[i,i] = 0;
i < j:
决策状态转移方程
m[i,j] = min(K){m[i,k]+m[k+1,j]+p[i-1]*p[k]*p[j]};
*/
/*
内存优化:
j >= i
上三角矩阵 压缩存储
主对角线扫描
无法降维压缩DP矩阵
*/
static const int N = 100;
static int p[(N<<1)+1] = {0},
m[N+1][N+1] = {0},
s[N+1][N+1] = {0};
static int matrixChain()
{
register int r = 0,k = 0,i = 0,j = 0;
for(i = 1;i <= N;++i)m[i][i] = 0;
//Optimal SubStructure
for(r = 2;r <= N;++r)
for(i = 1;i + r -1 <= N;++i)
{
j = i + r - 1;
m[i][j] = m[i+1][j]+p[i-1]*p[i]*p[j];
//INIT
s[i][j] = i;
//record of seperation/patathesis brackets
for(k = i+1;k<j;++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;
//UPD
}
}
}
return m[1][N];
}