最优矩阵链乘与最优三角剖分

 题目描述:给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2 ,…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。例如:

  A1={30x35} ; A2={35x15} ;A3={15x5} ;A4={5x10} ;A5={10x20} ;A6={20x25} ;

最后的结果为:((A1(A2A3))((A4A5)A6)) 最小的乘次为15125。
动态转移方程:
f(i, j) = min { f(i, k) + f(k+1, j) + P(i-1)P(k)P(j) }, i <= k < j
这里做一下说明:
f(i,j)球的是f(i,k)与f(k+1,j)的子结构即–A(i..k)与A(k+1..j)的代价与这两个部分的乘积代价,由于矩阵Ai的大小为p[i-1]*p[i],所以可以得到A(i..k)与A(k+1..j)的乘积代价为p[i-1]*p[k]*p[j]。
代码:

#include<iostream>
#include<algorithm>
using namespace std;
const int MAX = 105;
const int INF = 0x3f3f3f3f;
int dp[MAX][MAX];
int p[MAX];
int f(int i, int j) {//function 1  每次都递归分割两部分,最后合计
    if (dp[i][j] < INF)return dp[i][j];
    if (i == j)return 0;
    else {
        for (int k = i; k < j; k++) {
            dp[i][j] = min(dp[i][j], f(i, k) + f(k + 1, j) + p[i - 1] * p[k] * p[j]);
        }
    }

    return dp[i][j];
}
int main(void) {
    int n; cin >> n;
    for (int i = 0; i <= n; i++)
        cin >> p[i];
    memset(dp, INF, sizeof(dp));
    cout << f(1, n) << endl;;
    {//function 2
        for (int i = 0; i < n; i++)
            dp[i][i] = 0;
        for (int len = 2; len <= n; len++)//长度为2以上
            for (int i = 0; i <= n - len + 1; i++) {//i为起点位置
                int j = i + len - 1;//j为终点位置
                for (int k = i; k < j; k++) {//找最优点k
                    dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + p[i - 1] * p[k] * p[j]);
                }
            }
        cout << dp[1][n];
    }
    system("pause");
    return 0;
}

这里引述一位老哥的话:
我们来尝试走一次循环,以便理解为什么 for 循环的边界要这样子设置
首先是长度 len = 2,表示这一遍循环会计算所有Ai X Ai+1的情况,即两个连续的矩阵相乘的情况。i 会 从 1 循环到 n - 1,j 总是比 i 大 1,由于我们在初始化中已经把所有长度为1的情况,即dp[i][i]赋值为0,所以k循环里不会用到没有算过的值。
转自:http://blog.csdn.net/zhangxb35/article/details/38959047

2.最优三角剖分
这里就直接给一个链接,代码基本和上述问题的代码一致,此外那位博主写的很好。这里说一点,也是当时我迷惑的一点,总想归类这些问题,所以迷茫了一阵子,先说一下这个提的转移方程吧:

d(i,j)=max{d(i,k),d(k,j)+w(i,k,j)|i<k<j}
d(i,j)={0|i=j}

要说的是上面那个提用的子范围是i~k,k+1~j,和这个题有些出入,看了代码可以知道,k值根本没在子范围之内,但在后面的P(i-1)P(k)P(j)已经算进去了,所以就跳过了k,这个题就不一样了,这是一个几何问题,我的理解是:子范围表示的是以i-k为边的多边形和以k-j为边的多边形,后面计算的是i,k,j组成三角形的权值,所以两边范围是都需要k的,仅此。
http://blog.csdn.net/liuweiyuxiang/article/details/78827474

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值