动态规划&矩阵连乘

动态规划的概念

•     与分治方法类似

          分-治-合

•   与分治方法不同

          子问题之间并非相互独立

•     基本思想

           用一个表记录所有子问题的解,不管子问题是否被用到,只要它被计算过,就将其结果备份至表中

动态规划的基本要素

•      最优子结构

           利用问题的最优子结构性质,以自底向上的方式递归地从子问题的最优解逐步构造出整个问题的最优解。最优子结构是问题能用动态规划算法求解的前提。

•      重叠子问题

    •      递归算法求解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。这种性质称为子问题的重叠性质。

    •      动态规划算法,对每一个子问题只解一次,而后将其解保存在一个表格中,当再次需要解此子问题时,只是简单地用常数时间查看一下结果。

    •      通常不同的子问题个数随问题的大小呈多项式增长。因此用动态规划算法只需要多项式时间,从而获得较高的解题效率。

动态规划的步骤

•       找出最优解的性质

•       递归地定义最优值

•       以自底向上的方式计算出最优值

•       根据计算获得的最优值,构造最优解

矩阵连乘

•       问题

           给定n个矩阵(A1,A2,,An),其中AiAi+1是可乘的,求解这n个矩阵的连乘积A

•       矩阵连乘积A=A1A2A3A4

•       计算次序

           (((A1A2)A3)A4))

           ((A1(A2A3))A4)

           (A1((A2A3)A4))

           (A1(A2(A3A4)))

           ((A1A2)(A3A4))

•       最优子结构性质

           原问题的最优解包含其子问题的最优解

           A[1:n]的最优计算次序所包含的计算矩阵子链A[1:k]A[k+1:n]也是最优的

           数学归纳法可以证明

•       建立递归关系

           令A[i:j]所需的最少数乘次数为m[i][j].

           当i=j时,m[i][j]=0

           当i<j时,m[i][j]=m[i][k]+m[k+1][j] +pi-1*pk*pj

           构造递归关系

            将对应的m[i][j]的断开位置k记为s[i][j],可递归的构造最优解

•   递归求解    

 int matrixChainRecur(int i, int j){
if (i == j) return ;
int u = matrixChainRecur(i, i) + matrixChainRecur(i+, j)
+ p[i-] * p[i] * p[j];
s[i][j] = i;
for (int k = i + ; k < j; k++) {
int t = matrixChainRecur(i, k) + matrixChainRecur(k+, j)
+ p[i-] * p[k] * p[j];
if (t < u){
u = t;
s[i][j] = k;
}
}
return u;
}

•       在递归计算时,许多子问题被重复计算多次。这也是该问题可用动态规划算法求解的又一显著特征。

•       用动态规划算法解此问题,可依据其递归式以自底向上的方式进行计算。在计算过程中,保存已解决的子问题答案。每个子问题只计算一次,而在后面需要时只要简单查一下,从而避免大量的重复计算,最终得到多项式时间的算法

•       计算最优值

A1

A2

A3

A4

A5

A6

30´35

35´15

15´5

5´10

10´20

20´25

 # include<stdio.h>
# include<iostream>
using namespace std; int m[][],s[][],n,p[];
void matrixChain()
{
int i,j,k,r;
for(i=; i<=n; i++) m[i][i]=;
for(r=; r<=n; r++) //对角线
for( i=; i<=n-r+; i++) //行
{
j = r+i-; //列
m[i][j]=m[i][i]+m[i+][j]+p[i-]*p[i]*p[j];
s[i][j]=i;
for(k = i+; k<j; k++)
{
int temp=m[i][k]+m[k+][j]+p[i-]*p[k]*p[j];
if(temp<m[i][j])
{
m[i][j]=temp;
s[i][j]=k;
}
}
}
} void traceback(int i,int j)
{
if(i==j)return ;
traceback(i,s[i][j]);
traceback(s[i][j]+,j);
cout<<"Multiply A"<<i<<","<<s[i][j]<<"and A"<<s[i][j]+<<","<<j<<endl;
} int main()
{
cin>>n;
for(int i=; i<=n; i++)
cin>>p[i];
//测试数据可以设为六个矩阵分别为
//A1[30*35],A2[35*15],A3[15*5],A4[5*10],A5[10*20],A6[20*25]
//则p[0-6]={30,35,15,5,10,20,25}
//输入:30 35 15 5 10 20 25
matrixChain();
traceback(,n);
//最终解值为m[1][n];
cout<<m[][n]<<endl;
return ;
}

动态规划&矩阵连乘的更多相关文章

  1. BZOJ_3270_博物馆_(高斯消元+期望动态规划+矩阵)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3270 \(n\)个房间,刚开始两个人分别在\(a,b\),每分钟在第\(i\)个房间有\(p[ ...

  2. poj 3744 Scout (Another) YYF I - 概率与期望 - 动态规划 - 矩阵快速幂

      (Another) YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate into th ...

  3. (基于Java)算法之动态规划——矩阵连乘问题

    动态规划(Dynamic Programming):与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解.与分治法不同的是,适用于动态规划法求解 ...

  4. hdu 2604 Queuing(动态规划—>矩阵快速幂,更通用的模版)

    题目 最早不会写,看了网上的分析,然后终于想明白了矩阵是怎么出来的了,哈哈哈哈. 因为边上的项目排列顺序不一样,所以写出来的矩阵形式也可能不一样,但是都是可以的 //愚钝的我不会写这题,然后百度了,照 ...

  5. 51nod动态规划-----矩阵取数

    一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下向右走,求能够获得的最大价值. 例如:3 * 3的方格. 1 3 3 2 1 3 2 2 1 能够获得的最 ...

  6. Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...

  7. BZOJ2553 Beijing2011禁忌(AC自动机+动态规划+矩阵快速幂+概率期望)

    考虑对一个串如何分割能取得最大值.那么这是一个经典的线段覆盖问题,显然每次取右端点尽量靠前的串.于是可以把串放在AC自动机上跑,找到一个合法串后就记录并跳到根. 然后考虑dp.设f[i][j]表示前i ...

  8. 【题解】 bzoj1875: [SDOI2009]HH去散步 (动态规划+矩阵乘法)

    bzoj1875,懒得复制,戳我戳我 Solution: 看到这道题,看的出是个dp,每个点\(t\)时刻到达的方案数等于\(t-1\)到连过来的点方案数之和 但又因为题目有要求不能走一样的边回去不是 ...

  9. BZOJ5298 CQOI2018交错序列(动态规划+矩阵快速幂)

    显然答案为Σkb·(n-k)a·C(n-k+1,k).并且可以发现ΣC(n-k,k)=fibn.但这实际上没有任何卵用. 纯组合看起来不太行得通,换个思路,考虑一个显然的dp,即设f[i][j][0/ ...

随机推荐

  1. HW4.43

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  2. algorithm@ dijkstra algorithm & prim algorithm

    #include<iostream> #include<cstdio> #include<cstring> #include<limits> #incl ...

  3. UVa11404 - Palindromic Subsequence(区间DP+打印路径)

    题目大意 给定一个字符串,要求你删除尽量少的字符,使得原字符串变为最长回文串,并把回文串输出,如果答案有多种,则输出字典序最小的 题解 有两种解法,第一种是把字符串逆序,然后求两个字符串的LCS,并记 ...

  4. poj1873 The Fortified Forest 凸包+枚举 水题

    /* poj1873 The Fortified Forest 凸包+枚举 水题 用小树林的木头给小树林围一个围墙 每棵树都有价值 求消耗价值最低的做法,输出被砍伐的树的编号和剩余的木料 若砍伐价值相 ...

  5. opencv数据结构-MAT结构详解

    1.定义 OpenCV中的C结构体有 CvMat 和 CvMatND,但后续的应用中指出 CvMat 和 CvMatND 弃用了,在C++封装中用 Mat 代替,另外旧版还有一个 IplImage,同 ...

  6. eclipse项目出现红色叉叉解决方案

    方法一:导入的文件被删除了.解决方法:右击项目名,在弹出的菜单中选择“Bulid Path”-->“configure build path”-->“Source”,找到已被删除的那个文件 ...

  7. PowerShell运行cmd命令

    1.使用.exe扩展名 2.使用 cmd /c "" 3.在 PowerShell v3 中有另一种选择来解决这个问题,只需在命令行的任意位置添加 –% 序列(两个短划线和一个百分 ...

  8. Objective C assign&copy & retain区别

    什么是assign,copy,retain之间的区别? assign: 简单赋值,不更改索引计数(Reference Counting). copy: 建立一个索引计数为1的对象,然后释放旧对象 re ...

  9. javascript笔记08:javascript的if...else语句

    案例代码如下: <!DOCTYPE html> <html> <body> <p>点击这个按钮,获得基于时间的问候.</p> <but ...

  10. Linux 普通用户su命令切换控制

    1.编辑配置文件/etc/pam.d/su .将下面配置文件"#“去掉: # auth           required        pam_wheel.so use_uid 改成 a ...