zoukankan      html  css  js  c++  java
  • 基于DP的矩阵连乘问题

    当多个连续可乘矩阵做乘法时,选择正确的做乘顺序可以有效减少做乘法的次数,而选择的方法可以很容易的通过DP实现。

    原理就是对于每一个所求矩阵,搜索所有可以相乘得到它的方法,比较它们的消耗,选取最小值作为采用的方法。

    例如,给出矩阵A1(30*35) A2(35*15) A3(15*5) A4(5*10) A5(10*20) A6(20*25)

    我们另m(i,j)表示从第i个矩阵乘到第j个矩阵,并用p[i]表示矩阵的边长,如p[0]=30,p[1]=35......

    于是我们有:

    若i==j m(i,j)=0

    若i<j m(i,j)=min(m(i,k)+m(k+1,j)+p[i-1]*p[k]*p[j]),k=i,i+1,i+2...j-1(i<=k<j)

    实际操作过程中,我们往往用数组来记录每一个我们已经计算过的m(i,j)来提高效率。

    代码如下:

    主算法:

    #pragma once
    #include <algorithm>
    int matrix_p[MAX_V];
    int m[MAX_V][MAX_V];
    int matrix_V;
    
    int matrix_mul(int i, int j)
    {
        if (m[i][j] == INF)
        {
            for (int k = i;k < j;++k)
            {
                m[i][j] = std::min(m[i][j], matrix_mul(i, k) + matrix_mul(k + 1, j) + matrix_p[i - 1] * matrix_p[k] * matrix_p[j]);
            }
        }
        return m[i][j];
    }

    主程序:

    void matrix_chain_test()
    {
        cin >> matrix_V;
        for (int i = 0;i <= matrix_V;++i) cin >> matrix_p[i];
        for (int i = 0;i <= matrix_V;++i)
        {
            for (int j = 0;j <= matrix_V;++j)
            {
                m[i][j] = INF;
            }
            m[i][i] = 0;
        }
        int i, j;
        while (true)
        {
            cin >> i >> j;
            if (i == -1) break;
            cout << matrix_mul(i, j) << endl;
        }
    }

    PS:INF和MAX_V是两个很大的数,具体大家自己定就行。

  • 相关阅读:
    WPF 绘图 和动画
    BZOJ 4028 分块
    操作系统与计算机网络
    go排序-基数排序
    go排序-睡眠排序
    go排序-堆排序
    go排序-构建大顶堆
    go排序 插入排序
    go排序-选择排序
    go排序-冒泡排序
  • 原文地址:https://www.cnblogs.com/cielosun/p/5660691.html
Copyright © 2011-2022 走看看