算法提高 矩阵乘法 (区间dp)

问题描述
  有n个矩阵,大小分别为a0*a1, a1*a2, a2*a3, ..., a[n-1]*a[n],现要将它们依次相乘,只能使用结合率,求最少需要多少次运算。
  两个大小分别为p*q和q*r的矩阵相乘时的运算次数计为p*q*r。
输入格式
  输入的第一行包含一个整数n,表示矩阵的个数。
  第二行包含n+1个数,表示给定的矩阵。
输出格式
  输出一个整数,表示最少的运算次数。
样例输入
3
1 10 5 20
样例输出
150
数据规模和约定
  1<=n<=1000, 1<=ai<=10000。

题解:区间dp。

设dp[i][j]表示区间【i,j】中的最少运算次数。

那么转移方程为:

dp[ i ][ j ]=min(dp[ i ][ j ], dp[ i ][ k ]+dp[ k+1 ][ j ]+a[ i-1 ]*a[ k ]*a[ j ] ).


代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[1010];
ll dp[1010][1010];
ll solve(int n)
{
	ll sum=0;
	memset(dp,0,sizeof(dp));
	for(int len=2;len<=n;len++)
	{
		int j=len;
		for(int i=1;j<=n; i++,j++)
		{
			ll minn=1e18;
			for(int k=i;k<j;k++)
			{ 
				
				minn=min(minn,dp[i][k]+dp[k+1][j]+a[i-1]*a[k]*a[j]);
				
			}
			dp[i][j]=minn;
		}
	}
	return dp[1][n];
}
int main()
{
	int n;
	cin>>n;	
	for(int i=0;i<=n;i++)cin>>a[i];
	cout<<solve(n)<<endl;
	return 0;
} 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值