矩阵连乘问题(dp)

题目:

计算矩阵连乘积A1,A2,...,An,其中Ai的维度为p[i-1]*p[i]。输入规模n,p[0]~p[n],输出最少乘的次数和断点处也就是乘法顺序。

思路:

区间dp,m[i][j]表示从Ai到Aj区间内的最少乘的次数,枚举k(i<k<j),状态转移方程m[i][j]=max(m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j])。

用s[i][j]记录每次最少次数的时候是在哪个地方断开,即k的位置。详见代码。

代码:

#include <bits/stdc++.h>

using namespace std;
const int maxn=101;
int m[maxn][maxn],s[maxn][maxn],p[maxn];
int n;
void MatrixChain()
{
    for(int i=1; i<=n; i++)
        m[i][i]=0;
    for(int len=2; len<=n; len++)
    {
        for(int i=1; i<=n-len+1; i++)
        {
            int j=i+len-1;
            m[i][j]=m[i][i]+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;
                }
            }
        }
    }
}
void Traceback(int i,int j)
{
    if(i==j) return;
    Traceback(i,s[i][j]);
    Traceback(s[i][j]+1,j);
    printf("Multiply A%d,%d and A%d,%d\n",i,s[i][j],s[i][j]+1,j);
}
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=0;i<=n;i++)
            scanf("%d",&p[i]);
        MatrixChain();
        printf("%d\n",m[1][n]);
        Traceback(1,n);
    }
    return 0;
}


input

6
30 35 15 5 10 20 25
8
30 35 15 5 10 20 25 10 30

output

15125
Multiply A2,2 and A3,3
Multiply A1,1 and A2,3
Multiply A4,4 and A5,5
Multiply A4,5 and A6,6
Multiply A1,3 and A4,6
18625
Multiply A2,2 and A3,3
Multiply A1,1 and A2,3
Multiply A4,4 and A5,5
Multiply A4,5 and A6,6
Multiply A4,6 and A7,7
Multiply A4,7 and A8,8
Multiply A1,3 and A4,8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值