【JZOJ B组】矩阵

Description

N(2<=N<=500)个矩阵相乘,求进行乘法的最少次数,我们认为两个矩阵A(m*n)*B(n*p)的乘法次数为m*n*p次。

Input

第一行是整数N,接下来N行是对每个矩阵的描述,一行两个整数a,b,(1<=a,b<=50)a表示行,b表示列。输入确保能够相乘。

Output

一行输出最少乘法次数。

Sample Input

3
50 10
10 20
20 5

Sample Output

3500

思路

不会矩阵乘法的童鞋请自行百度。

首先,矩阵乘法满足结合律不满足分配率,而且题目保证能相乘,可以得到相邻的矩阵可以相乘合并,而且也可以与相邻的矩阵相乘。

题目就转换成把所有矩阵合并的代价,也就是区间DP

首先枚举区间长度,然后枚举左端点,再枚举一个K,把这个区间劈成两段。
转移时加上代价即可。
注意要更新合并矩阵的行列。

代码

#include
#include
#include
using namespace std;
const int maxn=577;
struct F
{
    int x,y,val;
}f[maxn][maxn];
int n;
int main()
{
    scanf("%d",&n);
    memset(f,0x3f,sizeof(f));
    for(int i=1; i<=n; i++) scanf("%d%d",&f[i][i].x,&f[i][i].y),f[i][i].val=0;
    for(int i=2; i<=n; i++)
    {
        for(int j=1; j<=n-i+1; j++)
        {
            int l=j,r=j+i-1;
            f[l][r].x=f[l][l].x; f[l][r].y=f[r][r].y;
            for(int k=l+1; k<=r; k++)
            {
                int m=f[l][k-1].x,n=f[l][k-1].y,p=f[k][r].y;
                f[l][r].val=min(f[l][k-1].val+f[k][r].val+m*n*p,f[l][r].val);
            }
        }
    }
    printf("%d",f[1][n].val);
}

你可能感兴趣的:(题解,dp,区间dp)