最优矩阵连乘

Problem 18: 最优矩阵连乘


Time Limit:1 Ms|  Memory Limit:128 MB
Difficulty:3

Description

一个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 C=4*5时,(A*B)*C=64而A*(B*C)=90。显然第一种顺序节省运算量。
现在给出N个矩阵,并输入N+1个数,第i个矩阵是a[i-1]*a[i]

Input

第一行n(n<=100)
第二行n+1个数

Output

最优的运算量

Sample Input

3
2 3 4 5

Sample Output

64

Hint

动态规划

思路:动态规划类题目,最优加括号结构, 今天刚看懂, 用一个二维数组存储最解, 

ans[i][j]为第i到第j个矩阵的最优加括号解, 最终要求的就是1到n的最优加括号解

ans[1][n], 因为求大问题要借助子问题的解, 所以要从小到大依次求解。具体请参考

优加括号算法。


#include 
#include 
#include 
#define MAX 101
unsigned int ans[MAX][MAX], p[MAX], n;         //数较大需要用无符号整形

int materixchain()
{
    int i, j, k, m, temp;                      //临时变量
	for(i = 0; i <= n; i++)
	{
	    ans[i][i] = 0;
	}
	for(m = 2; m <= n; m++)                    //m: 矩阵个数
	{
	    for(i = 1; i <= n-m+1; i++)             //i: 起始矩阵
		{
		    j = i + m - 1;                       //j: 结束矩阵
            ans[i][j] = 0xffffffff;               //初始化(大数)
			for(k = i; k < j; k++)                //k: 分界点 遍历起始矩阵到结束矩阵找出适当分界点
			{
			    temp = ans[i][k] + ans[k+1][j] + p[i-1]*p[j]*p[k];   //例如 1 2 3 则k = 1, i - 1 = 0, j = 2 (仔细琢磨下)
				if(temp < ans[i][j])
				{
				    ans[i][j] = temp;
				}
			}
		}
	}
	return ans[1][n];
}

int main()
{
	int i;
    scanf("%u", &n);
	for(i = 0; i <= n; i++)
	{
	    scanf("%u", &p[i]);
	}	
	printf("%u\n", materixchain());
    return 0;
}


你可能感兴趣的:(动态规划)