矩阵链乘

题目地址:http://218.5.241.13:8060/oj/showProblem.jsp?pid=1104

想了想,还是把原题也贴上来吧,这个oj看起来跟我们学校原来那个看起来好像啊,我们学校那个破oj就稀里糊涂的不见了,万一那天这个也一样,岂不很纠结。。。

Description

在科学计算中经常要计算矩阵的乘积。矩阵A和B可乘的条件是矩阵A的列数等于矩阵B的行数。若A是一个p×q的矩阵,B是一个q×r的矩阵,则其乘积C=AB是一个p×r的矩阵。其标准计算公式为:

由该公式知计算C=AB总共需要pqr次的数乘。
 

为了说明在计算矩阵连乘积时加括号方式对整个计算量的影响,我们来看一个计算3个矩阵{A1,A2,A3}的连乘积的例子。设这3个矩阵的维数分别为10×100,100×5和5×50。若按第一种加括号方式((A1A2)A3)来计算,总共需要10×100×5+10×5×50=7500次的数乘。若按第二种加括号方式(A1(A2A3))来计算,则需要的数乘次数为100×5×50+10×100×50=75000。第二种加括号方式的计算量是第一种加括号方式的计算量的10倍。由此可见,在计算矩阵连乘积时,加括号方式,即计算次序对计算量有很大影响。

于是,人们自然会提出矩阵连乘积的最优计算次序问题,即对于给定的相继n个矩阵{A1,A2,…,An}(其中Ai的维数为pi-1×pi ,i=1,2,…,n),如何确定计算矩阵连乘积A1A2…An的一个计算次序(完全加括号方式),使得依此次序计算矩阵连乘积需要的数乘次数最少。

Input

有若干种案例,每种两行,第一行是一个非负整数n表示矩阵的个数,n=0表示结束。接着有n行,每行两个正整数,表示矩阵的维数。

Ouput

对应输出最小的乘法次数。

Sample Input

310 100100 55 500

Sample Output

7500

Source

zmh


《算法导论》和《算法竞赛入门经典》中都有讲到的一道题,纠结了一阵子完全看不懂,打算放弃,转看《算法艺术与信息学竞赛》上的“括号配对”,因为之前在nyoj上见过这道题,又是纠结了好久,终于按着书上的伪代码AC了,没想到再回头看这道题立刻就思路清晰了,递归穷举加记忆解决~

f(i,j)=min{ f(i,k)+f(k+1,j)+a[i][1]*a[k][2]*a[j][2]  |  k=i to j-1 }

学动规到现在没多长时间,只理解到目前统一解题思路大概就是 穷举,不过由于动规题目的特殊性,在穷举的过程中会有很多问题是重复的,也就是说动规其实是一种可以省下很多时间的穷举法,至于省时间的方式知道两种:自底向上递推;自顶向下递归并记录,每次求解前先查记录。

代码备份:

#include <cstdio>
#include<cstring>
int s[1005][1005],a[1005][3];
int f(int i,int j)
{
	if(i==j) return 0;
	if(s[i][j]>=0) return s[i][j];
	s[i][j]=999999;
	for(int k=i;k<j;++k)
	{
		int tem=f(i,k)+f(k+1,j)+a[i][1]*a[k][2]*a[j][2];
		s[i][j]=(s[i][j]<tem) ? s[i][j]:tem;
	}
	return s[i][j];
}
int main()
{
	int num;
	while(1)
	{
		scanf("%d",&num);
		if(num==0) break;
		memset(s,-1,sizeof(s));
		for(int i=1;i<=num;++i)
			scanf("%d%d",&a[i][1],&a[i][2]);
		printf("%d\n",f(1,num));
	}
	return 0;
}

吐槽下这个oj题目没有给定n的范围,纠结。。。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值