SHUOJ - 算法题1 矩阵连乘问题(区间dp)
分析:设\(dp[i][j]\)为矩阵\(A[i:j]\)所需的最少乘法次数,则有dp方程:\(dp[i][j]=min\{dp[i][k]+dp[k+1][j]\}(i\leq k <j)\),当\(i=j\)时,\(dp[i][j]=0\).
则可以递归求解该问题,递归终止的条件是\(i=j\),自底向上地解决问题。枚举\([i,j)\)之间的每个k,并取其最小值。
因为该题需要输出解决方案,所以求解时,若\(dp[i][j] = dp[i][k]+dp[k+1][j]\),则用数组\(path[i][j]\)记录下这个k。
输出结果时,仍采用递归的方式,将一个括号内的视作一个子结构,递归终止的条件是区间中的元素仅有一个,此时打印单个矩阵。注意除了最外层的区间不用输出括号,加特判即可。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e2+5;
const int INF=0x3f3f3f3f;
typedef long long LL;
int a[maxn],b[maxn];
LL dp[maxn][maxn];
int path[maxn][maxn];
int n;
int dfs(int i,int j)
{
LL &ans=dp[i][j];
if(ans<INF) return ans;
if(i==j) return ans=0;
for(int k=i;k<j;k++){
int tmp=dfs(i,k)+dfs(k+1,j)+a[i]*b[k]*b[j]; //递归求解
if(tmp<ans){
ans=tmp; //不断更新最小值和其路径
path[i][j]=k;
}
}
return ans;
}
void print(int i,int j)
{
if(i==j){ //递归终止
printf("A%d",i); //输出独立矩阵
return;
}
if(i>1||j<n) printf("("); //最外层不要括号
print(i,path[i][j]); //递归进入子区间
print(path[i][j]+1,j);
if(i>1||j<n) printf(")"); //最外层不要括号
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int cas=0;
while(scanf("%d",&n)==1){
for(int i=1;i<=n+1;i++){
scanf("%d",&a[i]);
if(i>1) b[i-1] = a[i]; //后一个矩阵的行数等于前一个矩阵的列数
}
memset(dp,INF,sizeof(dp)); //初值置无穷大
memset(path,0,sizeof(path)); //路径
dp[1][n]=dfs(1,n);
printf("Case %d\n",++cas);
printf("%lld ",dp[1][n]);
print(1,n);
printf("\n");
}
return 0;
}
SHUOJ - 算法题1 矩阵连乘问题(区间dp)的更多相关文章
- P1005 矩阵取数游戏[区间dp]
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的\(m*n\)的矩阵,矩阵中的每个元素\(a_{i,j}\)均为非负整数.游戏规则如下: 每次取数时须从每行各取走一个元素,共n个.经过m次后 ...
- P1005 矩阵取数游戏 区间dp 高精度
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n \times mn×m的矩阵,矩阵中的每个元素a_{i,j}ai,j均为非负整数.游戏规则如下: 每次取数时须从每行各取走一个元素,共n ...
- 1166 矩阵取数游戏[区间dp+高精度]
1166 矩阵取数游戏 2007年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description [ ...
- ZOJ 1276 "Optimal Array Multiplication Sequence"(最优矩阵链乘问题+区间DP)
传送门 •题意 矩阵 A(n×m) 和矩阵 B(m×k) 相乘,共做 n×m×k 次乘法运算: 给你 n 个矩阵,求这 n 个矩阵的最优结合方式,使得做的总乘法运算次数最少: •题解 定义dp(i,j ...
- 最优矩阵连乘问题 区间DP
最优矩阵连乘积 Accepted: 10 Total Submit: 18Time Limit: 1000ms Memony Limit: 32768KB Description 在科学计算中经常要计 ...
- Good Vegetable 4级算法题 分值: [320/3120] 问题: [8/78]
1523 非回文 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 一个字符串是非回文的,当且仅当,他只由前p个小写字母 ...
- 面试必备:高频算法题终章「图文解析 + 范例代码」之 矩阵 二进制 + 位运算 + LRU 合集
Attention 秋招接近尾声,我总结了 牛客.WanAndroid 上,有关笔试面经的帖子中出现的算法题,结合往年考题写了这一系列文章,所有文章均与 LeetCode 进行核对.测试.欢迎食用 本 ...
- 经典算法题每日演练——第十七题 Dijkstra算法
原文:经典算法题每日演练--第十七题 Dijkstra算法 或许在生活中,经常会碰到针对某一个问题,在众多的限制条件下,如何去寻找一个最优解?可能大家想到了很多诸如“线性规划”,“动态规划” 这些经典 ...
- 经典算法题每日演练——第十六题 Kruskal算法
原文:经典算法题每日演练--第十六题 Kruskal算法 这篇我们看看第二种生成树的Kruskal算法,这个算法的魅力在于我们可以打一下算法和数据结构的组合拳,很有意思的. 一:思想 若存在M={0, ...
随机推荐
- MathType中如何快速输入空心字母
MathType输入数学公式时非常方便有效的,在文档中涉及到数学公式或者符号时都是使用MathType来进行的,因为它比Office自带的公式编辑器功能更为完善,使用起来更快捷.在数学公式中,在不同的 ...
- hdu 3667(拆边+最小费用最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3667 思路:由于花费的计算方法是a*x*x,因此必须拆边,使得最小费用流模板可用,即变成a*x的形式. ...
- pythonanywhere笔记
https://www.pythonanywhere.com Deploying an existing Django project on PythonAnywhere Deploying a Dj ...
- Lumen Carbon 日期及时间处理包
用到过的方法: 获取当前Y-m-d H:i:s Carbon::now()->toDateTimeString() 把 Y-m-d H:i:s 转 Y-m-d Carbon::parse('Y- ...
- JavaScript------创建节点
代码: <script type="text/javascript"> var i = 0; function add(){ var inputNode = docum ...
- kotlin正式由Goole公布为Android的最新开发语言
那么,现在大家开发Android的话一般来说都是直接用Java,这个没错吧(高手除外).嗯,那么用力那么久的Java,不知道大家是否有想过Java的不足,已经很多可以优化的地方呢.当然,新修订的版本中 ...
- ORA-00972: 标识符过长
若是拼接成的sql语句,请查找传递参数时字符型字段是否两边少了引号.
- Memcached 之 .NET(C#)实例分析
一:Memcached的安装 step1. 下载memcache(http://jehiah.cz/projects/memcached-win32)的windows稳定版(这里我下载了memcach ...
- 『SharePoint 2010』Sharepoint 2010 Form 身份认证的实现(基于SQL)
1:创建一个基于身份认证的应用程序(具体参见上篇基于AD) SQL-MembershipProvider 成员SQL-RoleManager 角色 2:修改管理中心,我们创建的应用程序,还有Web服务 ...
- 160308、java排序(形如1.1、1.2.1)
package com.rick.sample; import java.util.ArrayList; import java.util.Collections; import java.uti ...