最优矩阵链乘(动态规划)

一个n∗mn*mn∗m的矩阵由 nnn 行 mmm 列共 n∗mn*mn∗m 排列而成。两个矩阵A和B可以相乘当且仅当A的列数等于B的行数。一个nm的矩阵乘mp的矩阵,运算量为nmp。

矩阵乘法不满足分配律,但满足结合律。因此A∗B∗CA*B*CA∗B∗C既可以按顺序 (A∗B)∗C(A*B)*C(A∗B)∗C 也可以按 A∗(B∗C)A*(B*C)A∗(B∗C) 来进行。假设A、B、CA、B、CA、B、C 分别是 2∗3、3∗4、4∗52*3、3*4、4*52∗3、3∗4、4∗5 的,则 (A∗B)∗C(A*B)*C(A∗B)∗C 运算量是2∗3∗4+2∗4∗5=642*3*4+2*4*5=642∗3∗4+2∗4∗5=64,A∗(B∗C)A*(B*C)A∗(B∗C)的运算量是 3∗4∗5∗2∗3∗5=903*4*5*2*3*5=903∗4∗5∗2∗3∗5=90 .显然第一种顺序节省运算量。

给出n个矩阵组成的序列,设计一种方法把他们依次乘起来,使得总的运算量尽量小。假设第i个矩阵A[i]是P[i−1]∗P[i]P[i-1]*P[i]P[i−1]∗P[i]的(意味着这些矩阵可以按顺序链乘,所以只需要考虑区间相乘中区间的选取)。

输入

3
2 3 4 5

输出

64

实际上就是区间DP的模板。
我们用f(i,j)f(i,j)f(i,j)表示A[i]、A[i+1]...A[j]乘起来的最少运算数

状态转移方程

f(i,j)=min{f(i,j),f(i,k) + f(k+1,j) + P[i-1]*P[k]*P[j]}(i=<k<j)

边界为f(i,i)=0f(i, i) = 0f(i,i)=0。

我们使用闫氏DP分析法,实际上我们只需要考虑最后一步的操作即可。

本题我没有找到题目,找到了一道POJ上和这个几乎一模一样的题目,只不过那个题目是输入n只有n个数,所以相当于只有n-1个矩阵,所以会有微小的差别。


所以我们这里的答案是f[1][n - 1],转移方程的时候也有差别:

f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j] + a[i] * a[k + 1] * a[j + 1]);
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>using namespace std;
typedef long long ll;
const int N = 2007, M = 5000007, INF = 0x3f3f3f3f;int n, m;
int f[N][N];
int a[N];int main()
{while(scanf("%d", &n) != EOF && n){memset(f, 0x3f, sizeof f);for(int i = 1; i <= n; ++ i){scanf("%d", &a[i]);f[i][i] = 0;}for(int len = 2; len < n; ++ len){for(int i = 1; i <= n - len; ++ i){int j = i + len - 1;//注意再 -1 因为三个数才能组成两个可乘矩阵相乘f[i][j] = INF;for(int k = i; k < j; ++ k)
//!相当于是i到j但是需要的是i到j+1:例如第1个和第2个合并,对应到数上就是a[1]a[2]a[3]合并f[i][j] = min(f[i][j], f[i][k] + f[k + 1][j] + a[i] * a[k + 1] * a[j + 1]);}}printf("%d\n", f[1][n - 1]);//终点是 n-1 因为三个数才能组成两个可乘矩阵相乘}return 0;
}

【动态规划】区间DP - 最优矩阵链乘(另附POJ1651Multiplication Puzzle)相关推荐

  1. DP——最优矩阵链乘最优三角剖分

    最优矩阵链乘: 一个n*m的矩阵乘一个m*p的矩阵等于一个n*p的矩阵,运算量为mnp,现在有一组n个矩阵组成的序列,求运算量的最小值. 这是DP中的最优矩阵链乘问题,我们可以这么理解:用一个d[i] ...

  2. 0x53. 动态规划 - 区间DP(习题详解 × 8)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 文章目录 0x53. 动态规划 - 区间DP Problem A. 最优矩阵链乘 Problem B. ...

  3. 动态规划——区间dp

    在利用动态规划解决的一些实际问题当中,一类是基于区间上进行的,总的来说,这种区间dp是属于线性dp的一种.但是我们为了更好的分类,这里仍将其单独拿出进行分析讨论. 让我们结合一个题目开始对区间dp的探 ...

  4. 动态规划 —— 区间 DP

    [概述] 区间型动态规划,又称为合并类动态规划,是线性动态规划的扩展,它在分阶段地划分问题时,与阶段中元素出现的顺序和由前一阶段的区间中哪些元素合并而来有很大的关系. [思想] 区间 DP 实质上就是 ...

  5. 以空间换时间——动态规划算法及其应用:矩阵链相乘

    动态规划算法是5大算法基础中最重要的一个,它专门用来解决平面世界下的应用,即会多次使用二维数组. 当然动态规划算法是空间换时间的算法,也就是说:我们可以利用空间资源来使某算法问题的时间复杂度降到最低. ...

  6. [动态规划] 区间DP

    区间DP 石子合并问题 题目链接 https://www.acwing.com/problem/content/description/284/ 状态表示和状态转移 f [ i ] [ j ] f[i ...

  7. 【动态规划区间dp】蓝桥2019:最优包含

    字符串 二维dp: dp[ i ][ j ]表示S中前i个字符包含T中前j个字符至少修改S中前i个字符的字符数 如果S[ i ]==T[ j ] ,则不用修改第i个字符,dp[ i ][ j ] = ...

  8. 【动态规划】区间dp:P1005矩阵取数

    代码需要高精度,我不会

  9. 动态规划 —— 区间 DP —— 石子合并三讲

    石子合并问题是最经典的 DP 问题,其有如下3种题型: [任意合并] 1.问题: 有N堆石子,现要将石子有序的合并成一堆,规定如下:每次只能移动任意的2堆石子合并,合并花费为新合成的一堆石子的数量.求 ...

最新文章

  1. Wireshark实验HTTP
  2. 180万奖金!数据挖掘,NLP,CV等23个赛道,2020 科大讯飞AI大赛正式发布!
  3. CRM WEB UI 04明细界面添加按钮
  4. “==”和equals()那些事
  5. LiveVideoStack线上分享第三季(十三):腾讯云LiteAVSDK演进之路
  6. springmvc入门学习
  7. SQL2005中row_number()等函数的用法
  8. 由于在客户端检测到一个协议错误_HTTP协议,你了解多少?
  9. 如何查看文件的字符集
  10. Android 用MediaCodec ,MediaExtractor解码播放MP4文件
  11. tail,more查看日志(定点和翻页)
  12. 如何在自己开发的日程管理页面插入提醒功能_给大家推荐一款高颜值的日程管理类APP...
  13. Android初学第32天
  14. 微信小程序发送模板消息限制的问题
  15. 嵌入式大佬 | 嵌入式C语言知识点万字总结
  16. 两寸证件照的尺寸是多少?如何换两寸证件照的背景色?
  17. day64 url用法以及django的路由系统
  18. 六轴多关节机器人跟四轴机器人差别在哪里呢
  19. 免费开源JAVA报表工具对比 BIRT报表VS润乾报表之初体验
  20. 解决IDEA报错Address localhost:1099 is already in use

热门文章

  1. 在C++平台上部署PyTorch模型流程+踩坑实录
  2. 阿里、百度、字节跳动、京东、地平线等计算机视觉实习生面试经历分析,已成功上岸!...
  3. 浅谈RNN,LSTM和GRU
  4. 模拟PLC 的圆弧插补方式在VC中绘制圆弧
  5. 你应该知道的 5 个 Docker 工具
  6. CentOS SVN服务器管理多项目
  7. 使用slice和concat对数组的深拷贝和浅拷贝
  8. 转:一个android开发者独立开发社交app全过程
  9. HSQLDB安装与使用
  10. 超级变态的MySQL语句[2012-9-20]