算法导论第15章15.2-1

找了一段C实现的矩阵链乘法

#include "stdafx.h"
#include<stdio.h>
#include<string.h>
#define N 1000
int m[N][N];  //m[i][j]表示从第i个矩阵乘到第j个矩阵所需的最小代价
int s[N][N];  //s[i][j]表示最优值m[i][j]对应的分割点
int p[N];     //p[]代表矩阵链
void MATRIX_CHAIN_ORDER(int p[], int n) //对矩阵链p求解最佳组合方法
{
for (int i = 1; i <= n; i++) //子问题链长1时代价为0
m[i][i] = 0;


//对子问题链长2到n从小到大求出代价
for (int length = 2; length <= n; length++) //枚举子问题链长
{
//在对应链长下求出所有情况
for (int i = 1; i <= n - length + 1; i++)  //所有情况的开始位置
{
int j = i + length - 1;
m[i][j] = 999999;   //此时求出从i到j的最小代价m[i][j]=min{m[i][k]+m[k+1][j]+Pi-1*Pk*Pj}
for (int k = i; k <= j - 1; k++)
{
if (m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j] < m[i][j])
{
m[i][j] = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
s[i][j] = k;
}
}
}
}
}


void PRINT_OPTIMAL_PARENS(int s[][N], int start, int ends)//利用表s输出从start乘到ends的最优方案
{
if (start == ends)
printf("A[%d]", start);
else
{
printf("(");
PRINT_OPTIMAL_PARENS(s, start, s[start][ends]);
PRINT_OPTIMAL_PARENS(s, s[start][ends] + 1, ends);
printf(")");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int number;
printf("请输入待乘矩阵的个数:\n");
while (scanf_s("%d", &number) && number>0)
{
memset(m, 0, sizeof(m));
memset(p, 0, sizeof(p));
printf("请输入矩阵链:\n");
for (int i = 0; i <= number; i++)
scanf_s("%d", &p[i]);
MATRIX_CHAIN_ORDER(p, number);
PRINT_OPTIMAL_PARENS(s, 1, number);
printf("\n");
printf("请输入待乘矩阵的个数:\n");
}
return 0;
}

结果为((A5X10*A10X3)*((A3X12*A12*5)*(A5X50*A50X60)))


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值