博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
矩阵连乘问题
阅读量:4074 次
发布时间:2019-05-25

本文共 4142 字,大约阅读时间需要 13 分钟。

写给自己的话: 有时候虽然一道题懂做了,但是发现写解题报告时,要清楚把自己的思路描述出来却挺难的。做解题报告

不仅可以巩固、梳理知识,还可以加深理解。现在我还做得很不好, 一定要坚持! 加油! 

矩阵链乘问题:

例子:

(下面第二个{P1应该是P2)

void MatrixChain()  {      int i, j, k, t;      for(i = 1; i <= n; i++)          m[i][i] = 0;    //对角线赋值为0,是因为1个矩阵需做0次相乘  	for(r=2; r<=n; ++r){		for(i=1; i<=n-r+1; ++i){			j=i+r-1;			dp[i][j] = INF;  // INF表示一个很大的数			for(k=i; k<=j-1; ++k){				int temp=dp[i][k]+dp[k+1][j]+arr[i-1]*arr[k]*arr[j]; // arr数组的下标从0开始 。如果从1开始,各加1   				if(temp

RQNOJ 矩阵链乘法 

题目描述

我们都知道矩阵乘法:给定两个矩阵A和B,若A是n*r的矩阵,B是r*m的矩阵,则A*B的结果C是一个n*m的矩阵,且c[i,j]=∑a[i,k]*b[k,j],其中1<=k<=r。很显然,求出每个C[i,j]的过程中,我们都做了r次标量乘法。因此,总的标量乘法次数是n*m*r。

矩阵乘法满足结合律。换句话说,即使乘的顺序不同,结果都是相同的。例如,四个矩阵<A1,A2,A3,A4>相乘,会有五种不同的顺序:
(A1(A2(A3A4)))
(A1((A2A3)A4))
((A1A2)(A3A4))
((A1(A2A3))A4)
(((A1A2)A3)A4)
但是,不同的顺序会导致不同的效率——本题中,我们希望将给定的矩阵乘起来,并且使得总的标量乘法次数最少。注意,本题中给定的矩阵可以看作是环形的——第一个和最后一个矩阵可以相乘!为了满足矩阵乘法的合法性,输入数据保证对于任意相邻的矩阵,它们相邻的维数一定相等。
【数据规模和约定】
n<=100
所有矩阵的行、列数都是不超过1000的正整数。

输入格式

第一行一个整数n,表示矩阵个数。

接下来n行,每行两个整数,表示这个矩阵的行数和列数。

输出格式

一个整数,表示最少乘法次数。

4

2 3
3 5
5 10
10 2

样例输出

142

/*这一题和另外一题《能量项链》完全相同。注意这第一个矩阵可以和最后一个相连, 相当于是一个环处理环时,把这个环断掉,变成一条线,然后复制元素增长处理时,它有不同个起点。分别比较每个起点的结果,取其中最小的就是答案 */#include
#include
#define MAXN 250#define INF 2147483646int arr[MAXN];int dp[MAXN][MAXN];int main(){// freopen("input.txt","r",stdin); int i,n,a,b,r,j,k,s; scanf("%d",&n); for(i=1; i<=n; ++i){ scanf("%d %d",&arr[i],&a); arr[i+n]=arr[i]; // 复制元素 } int ans=2147483646; for(s=0; s<=n-1; ++s){ // 起点位置 memset(dp,0,sizeof(dp)); for(r=2; r<=n; ++r){ for(i=1; i<=n-r+1; ++i){ j=i+r-1; dp[i][j]=INF; for(k=i; k<=j-1; ++k){ int temp=dp[i][k]+dp[k+1][j]+arr[i+s]*arr[k+1+s]*arr[j+1+s]; if(temp

UVA  

/*这题也是矩阵连乘问题关键在于把砍木棍的过程逆过来看。即现在不是砍,而是把n段不同长度的木棍连成一整段每次两根木棍连接成一段时,这两根木棍的长度之和就是这次的费用。*/#include
#include
#define MAXN 55#define INF 2147483646int len[MAXN],arr[MAXN];int dp[MAXN][MAXN];int main(){ freopen("input.txt","r",stdin); int l,n,i,j,k,r; while(scanf("%d",&l),l){ scanf("%d",&n); len[0] = 0, arr[0]=0; for(i=1; i<=n; ++i){ scanf("%d",&arr[i]); len[i] = arr[i]-arr[i-1]; } arr[n+1]=l; len[n+1] = l-arr[n]; memset(dp,0,sizeof(dp)); for(r=2; r<=n+1; ++r){ for(i=1; i<=n+1-r+1; ++i){ j=r+i-1; dp[i][j] = INF; for(k=i; k<=j-1; ++k){ int temp=dp[i][k]+dp[k+1][j]+arr[j]-arr[i-1]; if(temp
/*	[NOI1995]  石子合并这题和上一题的木棍本质上都是一样的,只是石堆的放置是环状的。处理一下把环状变成链状就可以了然后比较各个不同起点得到答案*/#include
#include
#define MAXN 105#define oo 1147483646int arr[MAXN];int dp_min[MAXN][MAXN];int dp_max[MAXN][MAXN];inline int sum(int start,int end){ int sum=0; for(int i=start; i<=end; ++i) sum += arr[i]; return sum;}int main(){// freopen("input.txt","r",stdin); int N,i,j,s,k,r; while(scanf("%d",&N)!=EOF){ for(i=1; i<=N; ++i){ scanf("%d",&arr[i]); arr[i+N]=arr[i]; } memset(dp_min,0,sizeof(dp_min)); memset(dp_max,0,sizeof(dp_max)); int ans1=oo, ans2=-oo; for(s=0; s<=N-1; ++s){ for(r=2; r<=N+1; ++r){ for(i=1; i<=N-r+1; ++i){ j=r+i-1; dp_min[i][j] = oo; dp_max[i][j] = -oo; int total=sum(i+s,j+s); for(k=i; k<=j-1; ++k){ int t1=dp_min[i][k]+dp_min[k+1][j]+total; int t2=dp_max[i][k]+dp_max[k+1][j]+total; if(t1
dp_max[i][j]) dp_max[i][j]=t2; } } } if(dp_min[1][N]
ans2) ans2=dp_max[1][N]; } printf("%d\n%d\n",ans1,ans2); } return 0;}
矩阵链乘的打印:
FILE 9516
39.84%
2895
85.60%
#   Problem Verdict Language Run Time Submission Date
10095483 Accepted C++ 0.060 2012-05-10 05:39:06
/*UVa  348	Optimal Array Multiplication Sequence矩阵连乘 + 打印*/#include
#include
#include
using namespace std;#define MAXN 15#define INF 1073741824int m[MAXN];int dp[MAXN][MAXN],s[MAXN][MAXN];// 递归打印void Print(int i,int j){ if(i==j){ printf("A%d",i); return ; } else{ printf("("); Print(i,s[i][j]); printf(" x "); Print(s[i][j]+1,j); printf(")"); }}int main(){ freopen("input.txt","r",stdin); int n,r,b,i,j,k,cas=1; while(scanf("%d",&n)!=EOF){ if(!n) break; printf("Case %d: ",cas++); for(i=0; i
——      生命的意义,在于赋予它意义。 
                   原创 
 , By   D_Double

转载地址:http://buzni.baihongyu.com/

你可能感兴趣的文章
带WiringPi库的交叉笔译如何处理二之软链接概念
查看>>
Java8 HashMap集合解析
查看>>
自定义 select 下拉框 多选插件
查看>>
linux和windows内存布局验证
查看>>
Linux常用统计命令之wc
查看>>
fastcgi_param 详解
查看>>
搞定Java面试中的数据结构问题
查看>>
kprobe学习
查看>>
React Native(一):搭建开发环境、出Hello World
查看>>
React Native(二):属性、状态
查看>>
JSX使用总结
查看>>
React Native(四):布局(使用Flexbox)
查看>>
React Native(七):Android双击Back键退出应用
查看>>
Android自定义apk名称、版本号自增
查看>>
【剑指offer】q50:树中结点的最近祖先
查看>>
二叉树的非递归遍历
查看>>
【leetcode】Reorder List (python)
查看>>
【leetcode】Linked List Cycle (python)
查看>>
【leetcode】Candy(python)
查看>>
【leetcode】Sum Root to leaf Numbers
查看>>