UVA - 348 Optimal Array Multiplication Sequence (最优矩阵连乘)

题目大意:给你一些矩阵,你要写一个程式来决定该如何相乘的顺序,使得用到乘法的次数会最少。

思路:最优矩阵链乘问题,典型的动态规划题目。
该问题的子问题为“把Ai,Ai+1,……,Aj乘起来需要多少次乘法”,如果用dp(i,j)表示这个问题的子问题的值,
则状态转移方程:dp(i,j) = min{dp(i,k) + dp(k+1,j) + row(i)*col(k)*col(j)}
row代表当前矩阵的行,col代表当前矩阵的列。

总结:由于dp[i][j]的初始条件没有写好,结果wa了很多次,没考虑全,以为dp[i][j],初始化为0就好了。


#include <cstdio>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 15;
struct Matrix {
	int row,col;
}mat[N];
int dp[N][N], path[N][N];
void print_path(int l,int r) {
	if(l == r) {
		printf("A%d",l+1);
		return ;
	}else {
		printf("(");
		print_path(l,path[l][r]);
		printf(" x ");
		print_path(path[l][r]+1,r);
		printf(")");
	}
}
int main() {
	int n , cas = 1;
	while(scanf("%d",&n) != EOF && n) {
		for(int i = 0; i < n; i++) {
			scanf("%d%d", &mat[i].row, &mat[i].col);
		}
		memset(dp,0,sizeof(dp));
		memset(path,0,sizeof(path));
		for(int len = 1; len < n; len++) { //枚举长度
			for(int i = 0; i < n - len; i++) { //枚举起点
				int j = i + len;
				dp[i][j] = dp[i][i] + dp[i+1][j] + mat[i].row * mat[i].col * mat[j].col;
				path[i][j] = i;
				for(int k = i+1; k < j; k++) { //枚举中断点
					int tmp = dp[i][k] + dp[k+1][j] + mat[i].row * mat[k].col * mat[j].col;
					if(tmp < dp[i][j]) {
						dp[i][j] = tmp;
						path[i][j] = k;
					}
				}
			}
		}
		printf("Case %d: ",cas++);
		print_path(0,n-1);
		printf("\n");
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值