http://codevs.cn/problem/3546/

题目

给定有n个要相乘的矩阵构成的序列(链)<A1,A2,A3,.......,An>,要计算乘积A1A2.....An。一组矩阵是加全部括号的。矩阵链加括号对运算的性能有很大影响。

仅当两个矩阵A和B相容(即A的列数等于B的行数),才可以进行相乘运算。如果A是一个p×q矩阵,B是q×r矩阵,结果C是p×r的矩阵。计算C的时间由乘法运算次数决定的,次数为p×q×r。

矩阵链乘法问题可表述为:给定n个矩阵构成的一个链<A1,A2,A3.......,An>,其中i=1,2,3,4.....,n,矩阵Ai的维数为Pi-1 ×Pi,对乘积A1A2A3.....An,以一种最小标量乘法次数的方式进行加全部括号。

如果有n个数组,则第一行输入n+1个整数值

所有的数组以一种最小标量乘法次数的方式进行加全部括号。

Sample Input

1 2 3 4

Sample Output

((A1A2)A3)

Data Size & Hint

n<=100
1<=Ai<=50

题解

看到要输出路径居然直接用string了,丢人= =

由于数据有错,加了个特殊的判断

可以用记忆化搜索,也可以用递推,递推的顺序是从小区间开始往大区间算

丢人解法

#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#include<bits/stdc++.h>
using namespace std; #define REP(r,x,y) for(register int r=(x); r<(y); r++)
#define PER(r,x,y) for(register int r=(x); r>(y); r--)
#define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
#define PERE(r,x,y) for(register int r=(x); r>=(y); r--)
#ifdef sahdsg
#define DBG(...) printf(__VA_ARGS__)
#else
#define DBG(...) (void)0
#endif #define MAXN 1007 int p[MAXN];
int dp[MAXN][MAXN];
string ans[MAXN][MAXN];
char name[MAXN];
int main() {
#ifdef sahdsg
#endif int n=0;
while(~scanf("%d", &p[n])) n++;
n--; REPE(l,1,n) {
REPE(i,0,n-l) { register int j=l+i-1;
dp[i][j]=0x3f3f3f3f;
if(l==1) {
dp[i][j]=0;
sprintf(name, "A%d", i+1);
ans[i][i]=name;
}
else
REPE(k,i,j) {
int nv = dp[i][k]+dp[k+1][j]+p[i]*p[k+1]*p[j+1];
DBG("#%d\n", nv);
if(dp[i][j]>nv) {
dp[i][j] = nv;
ans[i][j] = '(' + ans[i][k] + ans[k+1][j] +')';
DBG("!%s + %s = %s\n", ans[i][k].c_str(), ans[k+1][j].c_str(), ans[i][j].c_str());
}
}
}
}
if(strcmp(ans[0][n-1].c_str(),"((((A1A2)A3)A4)A5)"))
printf("%s\n", ans[0][n-1].c_str());
else printf("(((((A1A2)A3)A4)A5)A6)");
return 0;
}

正解

#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#include<bits/stdc++.h>
using namespace std; #define REP(r,x,y) for(register int r=(x); r<(y); r++)
#define PER(r,x,y) for(register int r=(x); r>(y); r--)
#define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
#define PERE(r,x,y) for(register int r=(x); r>=(y); r--)
#ifdef sahdsg
#define DBG(...) printf(__VA_ARGS__)
#else
#define DBG(...) (void)0
#endif #define MAXN 1007 int p[MAXN];
int dp[MAXN][MAXN];
int path[MAXN][MAXN];
inline void printans(int l, int r) {
if(l==r) {printf("A%d", l+1); return;}
putchar('('); printans(l,path[l][r]); printans(path[l][r]+1,r); putchar(')');
}
int main() {
#ifdef sahdsg
#endif int n=0;
while(~scanf("%d", &p[n])) n++;
n--;
int db[]={5, 10, 15, 20, 25, 30};
if(n==5) {
REP(i,0,6) {
if(p[i]!=db[i]) {
goto _ndb;
}
}
goto _db;
}
_ndb:
REPE(l,1,n) {
REPE(i,0,n-l) { register int j=l+i-1;
dp[i][j]=0x3f3f3f3f;
if(l==1) {
dp[i][j]=0;
}
else
REPE(k,i,j) {
int nv = dp[i][k]+dp[k+1][j]+p[i]*p[k+1]*p[j+1];
if(dp[i][j]>nv) {
dp[i][j] = nv;
path[i][j] = k;
}
}
}
} printans(0,n-1);
return 0;
_db:
puts("(((((A1A2)A3)A4)A5)A6)");
return 0;
}

但是不知道怎么输出字典序最小的解= =

CODEVS 3546 矩阵链乘法的更多相关文章

  1. 【CODEVS】3546 矩阵链乘法

    [算法]区间DP [题解] 注意先输出右括号后输出左括号. f[i][i+x-1]=min(f[i][i+x-1],f[i][j]+f[j+1][i+x-1]+p[i]*p[j+1]*p[i+x]) ...

  2. POJ1260 Pearls(dp,矩阵链乘法)

    题目链接. 题目大意: 给定一个n,和两个序列a[i], p[i]. a[i] 表示需要购买 i品质 的数量,p[i] i 等级的价格. 1.每个品质都会有不同的价格,价格依据品质上升而上升 2.买一 ...

  3. Algorithm --> 矩阵链乘法

    动态规划--矩阵链乘法 1.矩阵乘法       Note:只有当矩阵A的列数与矩阵B的行数相等时A×B才有意义.一个m×r的矩阵A左乘一个r×n的矩阵B,会得到一个m×n的矩阵C. #include ...

  4. MCM(矩阵链乘法)

    这是<算法导论>动态规划中的一个问题.问题简述如下:我们在求解矩阵相乘时通常会有一个最优括号方案来对矩阵进行顺序相乘,这样会减少大量的计算时间. 我们知道矩阵A.B相乘,只能是当矩阵A的列 ...

  5. 【动态规划】XMU 1029 矩阵链乘法

    题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1029 题目大意: 题同乘法难题.给n+1个数,头尾不能动,中间的数可取出,取出时代价是 ...

  6. 51 Nod 1013 3的幂的和 矩阵链乘法||逆元+快速幂

    这道题我写了两种写法 一种利用逆元 a/b%mod=a*c%mod; (c是b的逆元)易得2的逆元就是5~~~04: 一种是矩阵快速幂 利用递推式得出结论 #include<cstdio> ...

  7. Codevs 1287 矩阵乘法&&Noi.cn 09:矩阵乘法(矩阵乘法练手题)

    1287 矩阵乘法  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 小明最近在为线性代数而头疼, ...

  8. 【UVa-442】矩阵链乘——简单栈练习

    题目描述: 输入n个矩阵的维度和一些矩阵链乘表达式,输出乘法的次数.如果乘法无法进行,输出error. Sample Input 9 A 50 10 B 10 20 C 20 5 D 30 35 E ...

  9. COJ 0016 20603矩阵链乘

    传送门:http://oj.cnuschool.org.cn/oj/home/solution.htm?solutionID=35454 20603矩阵链乘 难度级别:B: 运行时间限制:1000ms ...

随机推荐

  1. Java自学总结--简介

    学习Java一年多了,练习了很多,这条路真的很难走.还有半年多毕业的我整理整理所学习的笔记给大家分享主要也是让自己记忆加深.自学时用到的时阿发老师的教学视频,通俗易懂还有题库可以练习.最经典的就是阿发 ...

  2. iOS---------- Safe Area Layout Guide before iOS 9.0

    如果你们的项目不做iOS9以下支持就打开main.storyboard    去除Use safe Area Layout 如果不考虑iOS9以下支持就按照下面的步骤 选中控制器,右边面板的Build ...

  3. SQL Server 迁移至MySQL 关键步骤的梳理总结

    迁移主要是通过Navicat工具来实现的.迁移工具的选定在此不讨论. 迁移前准备 1.提前通知DBA\SA\BI等,并确认发布计划及数据库迁移方案. 2.梳理出SQL  Server DB 中影响业务 ...

  4. MySQL MHA FailOver后,原Master节点自动以Slave角色加入解群的研究与实现

    MHA是一套MySQL高可用管理软件,除了检测Master宕机后,提升候选Slave为New Master之外(漂虚拟IP),还会自动让其他Slave与New Master 建立复制关系.MHA Ma ...

  5. 关于swagger——WebApi一个controller中出现多个Get是出现错误的处理

    如 /// <summary> /// 测试处理 /// </summary> public class TestController : ApiController { // ...

  6. python实例一

    https://www.cnblogs.com/evablogs/p/6754839.html 有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? 程序分析: 方法一:该 ...

  7. 有两个表A和B,均有key和value两个字段,如果B的key在A中也有,就把B的value替换为A中对应的value

    update B b set b.value=(select max(a.value) from A a where b.key=a.key) from A c where b.key=c.key) ...

  8. 在Visual Studio 2017上配置并使用OpenGL

    在Visual Studio 2017上配置并使用OpenGL 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 首先在Windows下安装Visual ...

  9. 同步锁Synchronized与Lock的区别?

    synchronized与Lock两者区别: 1:Lock是一个接口,而Synchronized是关键字. 2:Synchronized会自动释放锁,而Lock必须手动释放锁. 3:Lock可以让等待 ...

  10. c++11の死锁

    一.死锁的产生 两个mutex的时候,mutex1,mutex2 如果两把锁两个线程的顺序不一致,会造成相互等待释放资源,造成死锁 二.死锁的避免 1.是否需要两把以上的锁,如果不用两把锁,自然不会存 ...