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]
矩阵乘法满足结合律,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个数
第二行n+1个数
Output
最优的运算量
Sample Input
3
2 3 4 5
2 3 4 5
Sample Output
64
Hint
动态规划
思路:动态规划类题目,最优加括号结构, 今天刚看懂, 用一个二维数组存储最解,
ans[i][j]为第i到第j个矩阵的最优加括号解, 最终要求的就是1到n的最优加括号解即
ans[1][n], 因为求大问题要借助子问题的解, 所以要从小到大依次求解。具体请参考最
优加括号算法。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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;
}
最优矩阵连乘动态规划
1737

被折叠的 条评论
为什么被折叠?



