动态规划-矩阵连乘(附备忘录法)

题目:矩阵连乘, 求解计算量最小的加括号方法。

输入: 按顺序输入各个矩阵的 行和列。

求解: 最少数乘次数和加括号方案。

(详细情况可自行百度)

题解: 用一个数组p[] 来存储参数, (但要进行处理一下, 如: 矩阵A 为 10*5 , B 为 5*15。P【】只记录 10, 5, 15)

用m【i】【j】 来表示 从 i->j 的数乘最小值。s[][]记录过程中的最优步骤.

const int maxn = 100;

int p[maxn], m[maxn][maxn], s[maxn][maxn]

void matrixChain(p[], int m[][maxn], int s[][maxn])
{
    int n=p.length-1;
    for(int i=1; i<=n; i++) m[i][i] = 0;
    for(int r=2; r<=n; r++)//控制行和列
    for(int i=1; i<=n-r+1; i++)//行
    {
        int j = i+r-1;//列
        m[i][j] = m[i+1][j] + p[i-1]*p[i]*p[j]//m[i][i]=0, 未加上。
        s[i][j] = i;
        for(int k=i+1; k<j; k++)
        {
            int t = m[i][k] + m[k+1][j] +p[i-1]*p[k]*p[j];
            if(t<m[i][j])
            {
                m[i][j]=t;
                s[i][j] = k;
            }
        }
    }
} 

构造最优解:

void traceback(int s[][maxn], int i, int j)
{
    if(i==j) return;
    traceback(s, i, s[i][j]);
    traceback(s, s[i][j]+1, j);
    printf("(%d, %d)  (%d, %d)", i, s[i][j], s[i][j]+1, j);
}
  traceback(s, i, j);

备忘录法:

int memoizedmatrixChain(int n)
{
    for(int i=1; i<=n; i++)
    for(int j=i; j<=n; j++)
    m[i][j] = 0;
    return lookupChain(1, n);
}

int lookupChain(int i, int j)
{
    if(m[i][j]>0) return m[i][j];
    if(i==j) return 0;
    int u=lookupChain(i+1, j) + p[i-1]*p[i]*p[j];
    s[i][j] = i;
    for(int k=i+1; k<j; k++)
    {
        int t = lookChain(i, k) + lookupChina(k+1, j) + p[i-1]*p[k]*p[j];
        if(t<u)
        {
            u=t;
            s[i][j] = k;
        }
    }
        m[i][j] = u;
        return u;
}

动态规划和备忘录法的区别:

备忘录法是动态规划的变形。 与动态规划算法一样, 备忘录方法用表格保存已解决的子问题的答案。 在下次需要解此问题时,只要简单的查看该子问题的解答, 而不必重新计算。

不同点:

与动态规划算法不同的是, 备忘录方法色递归方式是自顶向下的, 而动态规划是自底向上的递归的。 因此备忘录方法的控制结构与直接递归方法的控制结构相同, 区别在于备忘录方法为每个解过的子问题建立了备忘录以备需要时查看,避免了相同子问题的重复求解。

各有千秋:

一般情况下, 当一个问题的所有子问题都要至少解一次时,用动态规划算法比备用录方法好, 此时, 动态规划算法没有任何多余的计算。 同时, 对于许多问题, 常可利用其规则的表格存取方式,减少动态规划算法的计算时间和空间需求。 当子问题空间中的部分子问题可不必求解时, 用备忘录方法则较有利, 因为从其控制结构可以看出, 该方法只解那些确实需要求解的子问题。

时间: 2024-08-01 13:50:13

动态规划-矩阵连乘(附备忘录法)的相关文章

BNUOJ 34985 Elegant String 2014北京邀请赛E题 动态规划 矩阵快速幂

Elegant String Time Limit: 1000msMemory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main We define a kind of strings as elegant string: among all the substrings of an elegant string, none of them is a permutation of "0, 1,-, k

动态规划-矩阵链乘法

问题描述: 给定由n个要相乘的矩阵构成的序列(链)<A1,A2,...,An>,要计算乘积A1A2...An,可以将两个矩阵相乘的标准算法作为一个子程序,通过加括号确定计算的顺序(对同一矩阵链,不同的计算顺序所需要的计算次数大不相同). 目标问题:给定n个矩阵构成的矩阵链<A1,A2,...,An>,其中,i=1,2,...,n,矩阵Ai的维数为pi-1×pi,对乘积A1A2...An以一种最小计算次数加全部括号. 穷尽搜索: 令P(n)表示一串n个矩阵可能的加全部方案数.当n=1

矩阵连乘(备忘录方法:自顶向下递归)

#include<iostream> #include<vector> #include<iterator> #include<algorithm> using namespace std; /* *矩阵连乘(备忘录方法:自顶向下递归) */ vector<vector<int>> m;//m[i][j]表示矩阵Ai连乘到Aj的最少运算次数 vector<vector<int>> s;//s[i][j]记录矩阵

动态规划 矩阵链

算法导论上的题目,用动态规划算法解矩阵链乘法问题需要时间为O(n^3),空间为O(n^2). 问题描述: 给定n个矩阵构成的一个链(A1*A2*A3--*An),其中i=1,2,--n,矩阵Ai的维数为p(i-1)*p(i),对于乘积A1*A2*A3--*An以一种最小化标量乘法次数的方式进行加括号. /************************************************************************* > File Name: maxtrix_ch

算法导论 之 动态规划 - 矩阵链相乘

1 引言 在大学期间,我们学过高等数学中的线性规划,其中有关于矩阵相乘的章节:只有当矩阵A的列数与矩阵B的行数相等时,A×B才有意义.一个m×n的矩阵A(m,n)左乘一个n×p的矩阵B(n,p),会得到一个m×p的矩阵C(m,p).矩阵乘法满足结合律,但不满足交换律. 假设现要计算A×B×C×D的值,因矩阵乘法满足结合律,不满足交换律,即:A.B.C.D相邻成员的相乘顺序不会影响到最终的计算结果,比如: A×(B×(C×D)).A×((B×C)×D).(A×B)×(C×D).A×(B×C)×D.

【C++】 动态规划—矩阵链乘

[本文原创于Paul的博客园技术博客.] [本文欢迎转载,转载请以链接形式注明出处.] [本博客所有文章都经博主精心整理,请尊重我的劳动成果.] [C++] 动态规划-矩阵链乘 1.问题描述 给定n个矩阵构成的一个链给定{A1,A2,-,An},其中i=1,2,...,n.矩阵Ai的维数为pi-1*pi,如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少. 2.最优子结构 对乘积A1A2...An的任意加括号方法都会将序列在某个地方分成两部分,也就是最后一次乘法计算的

Codeforces 506E Mr. Kitayuta&#39;s Gift - 动态规划 - 矩阵

题目传送门 通往Codeforces的航线 通往vjudge的航线 题目大意 给定一个仅包含小写字母的串$s$,要求插入恰好$n$个小写字母字符,使得新串为回文串.问这样得到的新串有多少个是本质不同回文串. $1\leqslant |s| \leqslant 200,1 \leqslant n \leqslant 10^{9} $ 神题orz...orz...orz.Petr orz...orz...orz. 好了开始扯正题了. 任意位置插入并不太好处理.可以转化一下这个问题,求一个长度为$|s

《算法导论》读书笔记之动态规划—矩阵链乘法

前言:今天接着学习动态规划算法,学习如何用动态规划来分析解决矩阵链乘问题.首先回顾一下矩阵乘法运算法,并给出C++语言实现过程.然后采用动态规划算法分析矩阵链乘问题并给出C语言实现过程. 1.矩阵乘法 从定义可以看出:只有当矩阵A的列数与矩阵B的行数相等时A×B才有意义.一个m×r的矩阵A左乘一个r×n的矩阵B,会得到一个m×n的矩阵C.在计算机中,一个矩阵说穿了就是一个二维数组.一个m行r列的矩阵可以乘以一个r行n列的矩阵,得到的结果是一个m行n列的矩阵,其中的第i行第j列位置上的数等于前一个

动态规划 - 矩阵链的乘法问题

1.1具体实例 1.2子问题的划分和递推方程 2.动态规划算法的递归实现 3.动态规划算法的迭代实现 4.动态规划算法的要素 这里用矩阵链的乘法问题来说明动态规划算法的设计要素. \(A_1,A_2,..,A_n\)表示\(n\)个矩阵的序列,其中\(A_i\)为\(P_{i-1} \times P_i\)阶矩阵,\(i=1,2,...,n\). 向量\(P=<P_0,P_1,P_2..P_i>\)表示矩阵链的输入,其中\(P_0\)是\(A_1\)的行数,\(P_1\)是\(A_1\)的列数