矩阵连乘问题(动态规划算法)

问题描述:

具体可参考:https://blog.csdn.net/liufeng_king/article/details/8497607

代码如下:

#ifndef MATRIX_CHAIN_H
#define MATRIX_CHAIN_H

void matrix_chain(int *p, int n, int **m, int **s);
void traceback(int i, int j, int **s);

#endif
#include <iostream>
#include "matrix_chain.h"

using namespace std;

//利用动态规划算法获取最优值
void matrix_chain(int *p, int n, int **m, int **s)  //p:各个矩阵的列数,n:矩阵个数,m:m[i:j]矩阵i到j的相乘次数,s:对应的分开位置
{
    for (int i = 0; i < n; i++)
    {
        m[i][i] = 0;
    }
    for (int r = 2; r <= n; r++)
    {
        for (int i = 0; i < n - r + 1; i++)
        {
            int j = i + r - 1;
            m[i][j] = m[i + 1][j] + p[i - 1] * p[i] * p[j];
            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;
                }
            }
        }
    }
}

//利用s[i][j]获取最优解
void traceback(int i, int j, int **s)
{
    if (i == j)
        return;
    traceback(i, s[i][j], s);
    traceback(s[i][j] + 1, j, s);
    cout << "Multiply A" << i << " , " << s[i][j];
    cout << "and A" << (s[i][j] + 1) << " , " << j << endl;
}
#include <iostream>
#include "matrix_chain.h"

using namespace std;

int main(void)
{
    int matrix_num = 0;  //矩阵个数
    cout << "请输入矩阵个数:" << endl;
    cin >> matrix_num;

    int **m = new int *[matrix_num];
    for (int i = 0; i < matrix_num; i++)
        m[i] = new int[matrix_num];
    int **s = new int *[matrix_num];
    for (int i = 0; i < matrix_num; i++)
        s[i] = new int[matrix_num];
    int *p = new int[matrix_num];
    cout << "请输入各矩阵的列数:" << endl;
    for (int i = 0; i < matrix_num; i++)
    {
        cin >> p[i];
    }

    matrix_chain(p, matrix_num, m, s);
    traceback(0, matrix_num - 1, s);

    system("pause");
    return 1;
}

可结合我的另一篇关于贪心算法的博客进行比较,了解这两者的区别;

(http://www.cnblogs.com/zf-blog/p/8674932.html)

原文地址:https://www.cnblogs.com/zf-blog/p/8763090.html

时间: 2024-10-09 03:40:40

矩阵连乘问题(动态规划算法)的相关文章

实现矩阵连乘的动态规划算法

? 1.计算连个矩阵乘积的标准算法: //标准算法 void MatrixMultiply(int a[][MAXN], int b[][MAXN], int p, int q, int r) { int sum[MAXN][MAXN]; memset(sum, 0, sizeof(sum)); ? int i, j, k; //遍历矩阵a的行 for (k = 0; k < p; k++) { //遍历矩阵b的列 for (j = 0; j < r; j++) { //对应位置相乘 for

01背包问题的动态规划算法

01背包问题我最初学会的解法是回溯法,第一反应并不是用动态规划算法去解答.原因是学习动态规划算法的时候,矩阵连乘.最长公共子串等问题很容易将问题离散化成规模不同的子问题,比较好理解,而对于01背包问题则不容易想到将背包容量离散化抽象出子问题,从情感上先入为主也误以为动态规划算法不是解决01背包问题的好方法,实际上并不是这样的.另外,动态规划算法不对子问题进行重复计算,但是要自底向上将所有子问题都计算一遍,直到计算出最终问题的结果也就是我们要的答案,有点像爬山的感觉. 问题描述:给定n种物品和一背

五种常用算法之二:动态规划算法

动态规划算法: 基本思想: 动态规划算法通常用于求解具有某种最优性质的问题.在这类问题中,可能会有许多可行解.每一个解都对应于一个值,我们希望找到具有最优值的解.动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解.与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的.若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次.如果我们能够保存已解决的子问题的答案,而在需要时再找

动态规划算法之滚动数组的求解(C++)

虽然接触动态规划算法已经有一段时间,给一个01背包问题,能够做到一个表格简单粗暴下去,然后求得结果,但心里总觉得对这个算法理解十分不到位,抱着对算法的热爱,网上很多大牛的算法思维实在让我佩服的五体投地.在此讲一讲动态规划中滚动数组的求解方法,算是对这个知识点做一个记录,也希望有写的不妥的地方,大家能不吝赐教. 首先,我们先看看"滚动数组"的例题,大家可以参考http://www.lintcode.com/en/problem/house-robber/ 题意大概就是说:一个盗贼要去偷盗

动态规划算法--01背包问题

基本思想: 动态规划算法通常用于求解具有某种最优性质的问题.在这类问题中,可能会有许多可行解.每一个解都对应于一个值,我们希望找到具有最优值的解.动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解.与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解).若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很

动态规划算法之:最长公共子序列 & 最长公共子串(LCS)

1.先科普下最长公共子序列 & 最长公共子串的区别: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的.而最长公共子序列则并不要求连续. 2.最长公共子串 其实这是一个序贯决策问题,可以用动态规划来求解.我们采用一个二维矩阵来记录中间的结果.这个二维矩阵怎么构造呢?直接举个例子吧:"bab"和"caba"(当然我们现在一眼就可以看出来最长公共子串是"ba"或"ab") b a b c 0 0 0 a 0 1

动态规划算法求解0,1背包问题

首先我们来看看动态规划的四个步骤: 1. 找出最优解的性质,并且刻画其结构特性: 2. 递归的定义最优解: 3. 以自底向上的方式刻画最优值: 4. 根据计算最优值时候得到的信息,构造最优解 其中改进的动态规划算法:备忘录法,是以自顶向下的方式刻画最优值,对于动态规划方法和备忘录方法,两者的使用情况如下: 一般来讲,当一个问题的所有子问题都至少要解一次时,使用动态规划算法比使用备忘录方法好.此时,动态规划算法没有任何多余的计算.同时,对于许多问题,常常可以利用其规则的表格存取方式,减少动态规划算

关于动态规划算法的总结

动态规划算法.在T大某位老师的书中说就是递推+反复子问题. 动态规划算法的效率主要与反复子问题的处理有关. 典型的题目有 陪审团.最大公共子串问题 1,最大公共子串问题 这个是动态规划的基础题目. 动态规划就是递推和反复子结构. 确定了递推关系后.找到一个能极大地降低反复运算的子结构至关重要.选的好了,时间效率会非常好. 这个问题,最好还是设第一个串为a,长度为n,第二个串为b.长度m.那么最长的子序列长度为f(n,m) 当a[n]=a[m]时 f(n,m)=1+f(n-1,m-1) 否则f(n

动态规划算法解最长公共子序列LCS问题

第一部分.什么是动态规划算法 ok,咱们先来了解下什么是动态规划算法. 动态规划一般也只能应用于有最优子结构的问题.最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似).简单地说,问题能够分解成子问题来解决. 动态规划算法分以下4个步骤: 描述最优解的结构 递归定义最优解的值 按自底向上的方式计算最优解的值   //此3步构成动态规划解的基础. 由计算出的结果构造一个最优解.   //此步如果只要求计算最优解的值时,可省略. 好,接下来,咱们