POJ 0016 20603矩阵链乘

传送门:http://oj.cnuschool.org.cn/oj/home/solution.htm?solutionID=35454

20603矩阵链乘
难度级别:B; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B

试题描述

输入n个矩阵的维度和一些矩阵链乘的表达式,输出乘法的次数。如果乘法无法进行,输出error。假定A是m*n矩阵,B是n*p矩阵,则乘法的次数为m*n*p。如果矩阵A的列数不等于矩阵B的行数,则这两个矩阵无法进行乘法运算。例如:A是50*10的,B是10*20的,C是20*5的,则 A(BC)的乘法次数为10*20*5(BC的乘法次数)+50*10*5(A(BC)的乘法次数)=3500.

此题数据有误,2015-4-25已修正。


输入

第一行包括一个正整数n,表示共有n个矩阵参与运算。
接下来的n行,每行包括三部分,第一部分是矩阵的名字(一个大写字母),第二部分和第三部分各是一个正整数,分别表示该矩阵的行数和列数,这三部分之间有一个空格分隔。
最后一行包括一个矩阵运算的合法字符串(只包括小括号和上述矩阵的名称)

输出

按题目描述中的要求输出


输入示例

3
A 50 10
B 10 20
C 20 5
A(BC)

输出示例

3500

其他说明

数据范围:表达式的长度不超过100个字符。所有数据运算不会超过int32范围。

栈处理简单表达式。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<stack>
 7 using namespace std;
 8 const int maxn=100+10;
 9 int n;
10 struct Matrix{
11     int a,b;
12 }M[maxn];
13 inline int read(){
14     int x=0,sig=1;char ch=getchar();
15     while(!isdigit(ch)){if(ch==‘-‘) sig=-1;ch=getchar();}
16     while(isdigit(ch)) x=10*x+ch-‘0‘,ch=getchar();
17     return x*=sig;
18 }
19 inline void write(int x){
20     if(x==0){putchar(‘0‘);return;} if(x<0) putchar(‘-‘),x=-x;
21     int len=0,buf[15]; while(x) buf[len++]=x%10,x/=10;
22     for(int i=len-1;i>=0;i--) putchar(buf[i]+‘0‘);return;
23 }
24 int solve(Matrix& a,Matrix b){
25     int ans=-1;
26     if(a.b==b.a){ans=a.a*b.b*b.a;a.b=b.b;}
27     return ans;
28 }
29 void init(){
30     n=read();
31     char ch;
32     for(int i=1;i<=n;i++){
33         do ch=getchar(); while(isalpha(ch)!=1);
34         int id=ch-‘A‘;
35         M[id].a=read();
36         //write(M[id].a); putchar(‘\n‘);
37         M[id].b=read();
38         //write(M[id].b); putchar(‘\n‘);
39     }
40     return;
41 }
42 stack<Matrix> S;
43 void work(){
44     int ans=0;
45     char s[maxn];scanf("%s",s);
46     int len=strlen(s);
47     for(int i=0;i<len;i++){
48         if(isalpha(s[i])) S.push(M[s[i]-‘A‘]);
49         else if(s[i]==‘)‘){
50             Matrix t2=S.top();S.pop();
51             Matrix t1=S.top();S.pop();
52             int t=solve(t1,t2);
53             if(t<0){puts("error");return;}
54             ans+=t;S.push(t1);
55         }
56     }
57     Matrix t2=S.top();S.pop();
58     Matrix t1=S.top();S.pop();
59     int t=solve(t1,t2);
60     if(t<0){puts("error");return;}
61     ans+=t;
62     write(ans);
63     return;
64 }
65 void print(){
66     return;
67 }
68 int main(){
69     init();work();print();return 0;
70 

}
时间: 2024-10-10 10:02:00

POJ 0016 20603矩阵链乘的相关文章

矩阵链乘(Matrix Chain Multiplication)

输入n个矩阵的维度和一些矩阵链乘表达式,输出乘法的次数.如果乘法无法进行,则输出error.假定A是m*n矩阵,B是n*p矩阵,那么A*B是m*p矩阵,乘法次数为m*n*p.如果A的列数不等于B的行数,则乘法无法进行. 例如,A是50*10的,B是10*20的,C是20*5的,则(A(BC))的乘法次数为10*20*5(BC的乘法次数) +50*10*5(A(BC)的乘法次数) = 3500. #include<cstdio> #include<stack> #include<

矩阵链乘

矩阵链乘之结构体构造函数 struct构造函数,和构造函数的重载函数长这个样子,和C++的构造函数差不过. struct Dog { Dog() { name = "wangwang"; age = 10; } string name; int age; }; struct Dog { Dog() { name = "Ao di"; age = 2; } Dog(string n) { name = n; age = 10; } Car(string n, int

动态规划之矩阵链

dp有很多个经典应用,矩阵链是其中一个. 对于我这种数学不好的人,需要回顾矩阵性质. 若矩阵A的维数是p×q,矩阵B的维数是q×r,则A与B相乘后所得矩阵AB的维数是p×r.按照矩阵相乘的定义,求出矩阵AB中的一个元素需要做q次乘法(及q-1次加法).这样,要计算出AB就需要做p×q×r次乘法.由于加法比同样数量的乘法所用时间要少得多,故不考虑加法的计算量. 看下面一个例子,计算三个矩阵连乘{A1,A2,A3}:维数分别为10*100 , 100*5 , 5*50 按此顺序计算需要的次数((A1

poj 3070 Fibonacci (矩阵快速幂求斐波那契数列的第n项)

题意就是用矩阵乘法来求斐波那契数列的第n项的后四位数.如果后四位全为0,则输出0,否则 输出后四位去掉前导0,也...就...是...说...输出Fn%10000. 题目说的如此清楚..我居然还在%和/来找后四位还判断是不是全为0还输出时判断是否为0然后 去掉前导0.o(╯□╰)o 还有矩阵快速幂的幂是0时要特判. P.S:今天下午就想好今天学一下矩阵乘法方面的知识,这题是我的第一道正式接触矩阵乘法的题,欧耶! #include<cstdio> #include<iostream>

UVa 442 矩阵链乘及scanf说明符中的\n

题目:计算题给矩阵相乘次序所需的相乘次数.   我们已知的m*n和n*k矩阵相乘,得到的是m*k矩阵,但需要的相乘次数是m*n*k(开始当成了m*k %>_<%).evaluate,求值 思路:每个矩阵用结构体表示,有名字.行.列.需要计算的次数.矩阵相乘的过程用栈来模拟.遇到左括号(,压栈这是自然的.遇到一个矩阵时,检查栈顶,如果栈顶元素是左括号,则压栈,否则就是矩阵,则比较栈顶矩阵和输入矩阵是否匹配,如果匹配则修改栈顶矩阵的列.计算次数,这样输入矩阵对栈顶进行了修改,相当于完成了相乘,这时

矩阵乘法及矩阵链乘的快速幂优化

一.矩阵乘法 1 struct datatype 2 { 3 int a[2][2]; 4 }; 5 datatype multiple(datatype x,datatype y) 6 { 7 datatype res; 8 memset(res.a,0,sizeof(res.a)); 9 for(int i=0;i<=1;i++) 10 { 11 for(int j=0;j<=1;j++) 12 { 13 for(int k=0;k<=1;k++) 14 { 15 res.a[i][

矩阵链相乘问题

问题描述 给定n个矩阵A1,A2 ,...,An,相邻的矩阵是可乘的,如何确定一个最优计算次序,使得以此次序计算需要的数乘次数最少? 计算次序对计算性能的影响: 假设n=3,A1,A2,A3的维数分别为10×100,100×5,5×50.考察A1×A2×A3需要的数乘次数,有以下 两种计算方式: (1)(A1×A2)×A3:10×100×5+10×5×50=7500 (2) A1×(A2×A3):100×5×50+10×100×50=75000 通过这个简单的例子足以说明,矩阵的计算次序对计算性

算法13---动态规划矩阵链乘法

算法13---动态规划矩阵链乘法 矩阵链乘法是动态规划里面使用到的一个例子 1 两个矩阵的计算 那么对于一个矩阵的乘法,首先如果是两个矩阵的乘法,那么如何实现呢? 注意到我们使用二维数组表示矩阵,但是二维数组不能作为函数的返回值.具体实现如下 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 5 #define a_rows 3 6 #define a_columns 4 7 #define

动态规划-矩阵链乘法

问题描述: 给定由n个要相乘的矩阵构成的序列(链)<A1,A2,...,An>,要计算乘积A1A2...An,可以将两个矩阵相乘的标准算法作为一个子程序,通过加括号确定计算的顺序(对同一矩阵链,不同的计算顺序所需要的计算次数大不相同). 目标问题:给定n个矩阵构成的矩阵链<A1,A2,...,An>,其中,i=1,2,...,n,矩阵Ai的维数为pi-1×pi,对乘积A1A2...An以一种最小计算次数加全部括号. 穷尽搜索: 令P(n)表示一串n个矩阵可能的加全部方案数.当n=1