//Dynamic Programming经典算法之矩阵连乘链问题
//Author: milo
//Email: 498638441@qq.com
//Date: 2011/11/16 16:50
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
static int m[6][6];//m[i][j]存储子问题的最优解
static int s[6][6];//s[i][j]存储子问题的最佳分割点
//存储各个矩阵的列数以及第一个矩阵的行数(作为第0个矩阵的列数)
static int p[7]={30,35,15,5,10,20,25};
static void matrix()
{
//1. 初始化
int i;
for(i=0;i<6;i++)
m[i][i]=0;//最小子问题仅含有一个矩阵
//2. 扫描i<j的所有m[i][j]的子问题的最小消耗(既从含2-6个矩阵组成的矩阵序列递增处理)
int j;
for(i=2;i<=6;i++)
for(j=0;j<6-i+1;j++){//以上两个for循环包含了升序的所有子问题
m[j][j+i-1]=INT_MAX;//针对一个具体的子问题,扫描每一个可能的分割点
int k;
for(k=0;k<i-1;k++){//k代表分割点
if(m[j][j+i-1]>m[j][j+k]+m[j+k+1][j+i-1]+p[j]*p[j+k+1]*p[j+i]){
m[j][j+i-1]=m[j][j+k]+m[j+k+1][j+i-1]+p[j]*p[j+k+1]*p[j+i];
s[j][j+i-1]=k;//记录分割点
}
}
}
}
static void print_matrix(int left_index,int right_index)//递归打印输出
{
if(left_index==right_index)
printf("A%d",left_index);
else{
printf("(");
print_matrix(left_index,left_index+s[left_index][right_index]);
print_matrix(left_index+s[left_index][right_index]+1,right_index);
printf(")");
}
}
int main(int argc,char *argv[])
{
matrix();
printf("min total cost:\t%d\n",m[0][5]);
print_matrix(0,5);
printf("\n");
return 0;
}
输出截图: