最优二叉查找树的一道思考习题

同最优二叉查找树一样,矩阵连乘问题也是一个卡特兰数问题(其动态规划的构造过程都很像)

分析解答:
a,铺垫的数学知识首先要搞清楚矩阵相乘是怎么乘的:

1)对于连续的n个矩阵相乘 A1 * A2 *A3.........An,其乘法顺序可以是任意的,可以在上面加括号,改变做乘法的顺序,例如 A*B*C三个矩阵相乘可以A*(B*C)

也可以直接按从左到右的顺序。连续的两个矩阵的位数必须满足m*p,p*n才能相乘,且相乘后的结果是个m*n的矩阵。(线性代数的知识)

2)对于2个m*p,p*n的矩阵相乘,共做乘法次数为 m*n*p 次。这是预备知识,知道矩阵连续的乘法的运算次数跟运算顺序有关后,就很容易举出例子了,略。
b,卡特兰数个,证明很麻烦,有时间看了组合数学再来看
c,重点是要解决这个问题。

设M[i , j]表示从第 i 个矩阵到第 j 个矩阵连乘的最少乘法次数,(i 从 0 编号),我们最终的目标是求 M[0 , n-1]。

Ai *.......Ak * Ak+1.....Aj

假设要得到这个式子的值(即从矩阵
i 连乘到矩阵 j),所作的最后一个矩阵乘法是在矩阵 k 后(注意准确的描述位置)断开的(即左右都已乘运算好),那么容易得到

其递推式:

M[i ,
j]  =  min{ M[i , k] + M[k+1 , j]  + p[i - 1] * p[ k ] * p[ j ]
}         i   <=  
k   <=   j-1

其中 di 是矩阵 Ai 的第一维,dk+1是断开处矩阵 Ak 的第二维(即Ak+1的第一维,是一样的),dj+1是最后一个矩阵 Aj 的第二维。

得到这个式子也是一个逆向思维的过程。

可以用矩阵连乘的动态规划构造过程与最优二叉查找树比较下,发现其构造非常相似(在前面一篇dp之什么叫做professional中提到过,不再详述)

实现:

初始条件:M[i , i]
= 0

填表顺序:鉴于其递推式与最优二叉查找树相似,填表顺序也是按对角线的,自己画画就知道了。

代码也跟最优二叉查找树的控制逻辑相似:

package Section8;

/*第八章 动态规划   课后习题:矩阵连乘*/

public class MatEven {

/**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
       
int[] Dim = {30,35,35,15,15,5,5,10,10,20,20,25};
        int
result = MatEven(Dim);

System.out.println("\n动态规划求的的最优策略相乘顺序导致的最少乘法数为:" +
result);
    }
   
    public static int MatEven(int[]
Dim){
        //接受n个矩阵的维度数组Dim大小为2n
        int n =
Dim.length / 2;        //有n个矩阵,编号0...n-1,编号为k的矩阵的维数是Dim[2k] * Dim[2k+1]
       
        int[][]
Result = new int[n][n];       
//最小代价矩阵
       
        //初始化
        for(int i = 0;i < n;i++)
            Result[i][i] = 0;
       
        //沿对角线填矩阵
        for(int d = 1;d <= n-1;d++)      //共n-1条对角线需要填
        {
            for(int i = 0;i <= n-d-1;i++)    //第d条对角线的第一个点横坐标为d
            {
                //int j = i - d;
                int j = i
+ d;        //在第d条对角线上的点,横纵坐标的关系是j = i + d
               
                //这样就确定了一个位置(i,j)的坐标,然后来填(i,j)
                int Min =
1000000000;
                for(int k = i;k <= j-1;k++)        //从第k个矩阵后面断开
                {
                    //动态规划状态转移方程
                    int temp
= Result[i][k] + Result[k+1][j] + (Dim[2*i] * Dim[2*k + 1] * Dim[2*j+1]);
                    if( temp < Min)
                        Min = temp;
                }
               
                Result[i][j] = Min;
            }
           
        }
       
        return
Result[0][n-1];
    }
}

上面用一个数组接受一个连乘的矩阵的维数,

例如连乘的矩阵维数是:30*35  35*15  15*5  5*10  10*20  20*25

用动态规划求解得到的最佳乘法次数是:

动态规划求的的最优策略相乘顺序导致的最少乘法数为:15125

直接返回矩阵的话就可以得到整个M[i
, j]的值

如果按照从左到右的顺序做乘法,是远远不止这个次数的。

-------------------------------------------------------------------------

当然,再做一些处理,就还可以得到具体的次序,类似于最优二叉查找树,就是要记录动态规划产生的过程,略

----------------------------------------------------------------------------------------------

总结:

矩阵连乘问题是个卡特兰数问题

其动态规划的构造过程非常类似于最优二叉查找树

矩阵连乘的最有子结构是什么?

DP之矩阵连乘问题的更多相关文章

  1. 【loj2325】「清华集训 2017」小Y和恐怖的奴隶主 概率dp+倍增+矩阵乘法

    题目描述 你有一个m点生命值的奴隶主,奴隶主受伤未死且当前随从数目不超过k则再召唤一个m点生命值的奴隶主. T次询问,每次询问如果如果对面下出一个n点攻击力的克苏恩,你的英雄期望会受到到多少伤害. 输 ...

  2. poj 3744 Scout YYF I(概率dp,矩阵优化)

    Scout YYF I Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5020   Accepted: 1355 Descr ...

  3. bzoj 1009 [HNOI2008]GT考试(DP+KMP+矩阵乘法)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1009 [题意] 给定一个字符串T,问长度为n且不包含串T的字符串有多少种. [思路] ...

  4. 基于DP的矩阵连乘问题

    当多个连续可乘矩阵做乘法时,选择正确的做乘顺序可以有效减少做乘法的次数,而选择的方法可以很容易的通过DP实现. 原理就是对于每一个所求矩阵,搜索所有可以相乘得到它的方法,比较它们的消耗,选取最小值作为 ...

  5. 【POJ2778】DNA Sequence 【AC自动机,dp,矩阵快速幂】

    题意 题目给出m(m<=10)个仅仅由A,T,C,G组成的单词(单词长度不超过10),然后给出一个整数n(n<=2000000000),问你用这四个字母组成一个长度为n的长文本,有多少种组 ...

  6. 2018.09.27 bzoj2510: 弱题(概率dp+循环矩阵优化)

    传送门 简单概率dp. 显然每次转移的式子可以用一个矩阵表示出来: 这个是循环矩阵. 因此只用维护第一行快速幂一波就行了. 代码: #include<bits/stdc++.h> #def ...

  7. 【洛谷4719】 动态dp(树链剖分,dp,矩阵乘法)

    前言 其实我只是为了过掉模板而写的ddp,实际应用被吊着锤 Solution 并不想写详细的过程 一句话过程:将子树中轻儿子的贡献挂到这个点上面来 详细版:(引用yyb) 总结一下的话,大致的过程是这 ...

  8. bzoj 2510: 弱题 概率期望dp+循环矩阵

    题目: Description 有M个球,一开始每个球均有一个初始标号,标号范围为1-N且为整数,标号为i的球有ai个,并保证Σai = M. 每次操作等概率取出一个球(即取出每个球的概率均为1/M) ...

  9. 【BZOJ2510】弱题 期望DP+循环矩阵乘法

    [BZOJ2510]弱题 Description 有M个球,一开始每个球均有一个初始标号,标号范围为1-N且为整数,标号为i的球有ai个,并保证Σai = M. 每次操作等概率取出一个球(即取出每个球 ...

随机推荐

  1. sql server 2008 r2 出问题

    1.想利用sql2008的数据挖掘功能,以为是没有安装全,所以就卸载了. (1)利用Windows Installer Clean UP将以前的卸载干净 (2)出现了Could not open ke ...

  2. .net调用java webservice基于JBOSS服务器 学习笔记(一)

    1.遇到数组类型或List等复杂数据类型是,需要对其进行包装,就是将复杂数据类型放到一个类里面: public class VOCargoJTWS { /** JT列表 */ private List ...

  3. http://www.blogjava.net/nokiaguy/category/37087.html

    http://www.blogjava.net/nokiaguy/category/37087.html

  4. HW7.16

    import java.util.Arrays; public class Solution { public static void main(String[] args) { int row = ...

  5. How to install php evn on ubuntu

    1. How to install PHP EVN 打开终端,也就是命令提示符. 我们先来最小化组建安装,按照自己的需求一步一步装其他扩展.命令提示符输入如下命令: 1 sudo apt-get in ...

  6. 第一百九十七-第二百天 how can I 坚持

    又是四天,how 快. 第一天,晚上要坐车回济南,没下班就躁动了.晚上高铁竟然是知道济南西,中间没有停,到济南九点半,去刘松家又吃了一顿.喝了不少酒.挺爽. 第二天,早上五点多就醒了,睡的婚床,哈哈, ...

  7. Hadoop MapReduce概念学习系列之mr程序组件全貌(二十)

    其实啊,spilt是,控制Apache Hadoop Mapreduce的map并发任务数,详细见http://www.cnblogs.com/zlslch/p/5713652.html map,是m ...

  8. 从Mac的Finder中访问你的iCloud文档

    [从Mac的Finder中访问你的iCloud文档] 从OS X 10.7.2开始,iCloud就深入Mac当中,我们也可以在Finder中访问储存在iCloud中的文件,甚至当你拥有多台Mac的时候 ...

  9. Android中使用gzip传递数据

    HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术.大流量的WEB站点常常使用GZIP压缩技术来减少文件大小,减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时 ...

  10. C++中回调函数(CallBack)的使用

    如果试图直接使用C++的成员函数作为回调函数将发生错误,甚至编译就不能通过. 其错误是普通的C++成员函数都隐含了一个传递函数作为参数,亦即“this”指针,C++通过传递this指针给其成员函数从而 ...