矩阵连乘问题--动态规划

矩阵连乘问题–动态规划

题目描述

给定n个矩阵{A1A2…An},其中Ai和Ai+1是可乘的,考察这n个矩阵的连乘积A1A2…An。由于矩阵的乘法满足结合律,故计算矩阵的连乘积有许多不同的计算次序,而不同的计算次序,所需要计算的连乘次数也是不同的,求解连乘次数最少的矩阵连乘最优次序。

例如:
矩阵连乘积A1A2A3,3个矩阵的维数分别为10100,1005和550,连乘时加括号的方式有:
((A1
A2 )* A3) 数乘次数:10* 100* 5+10* 5* 50=7500
(A1*(A2*A3)) 数乘次数:100 * 5 * 50+10 * 100 * 50=75000
显然,第一种方法优于第二种。

输入格式:

第一行为一个整数N,表示有N个矩阵;接下来每行分别输入每个矩阵的行数和列数。

输出格式:

输出所计算出的矩阵最小连乘次数。

输入示例:
4
50 10
10 40
40 30
30 5
输出示例:
10500
思路解析:

设计算A[i: j],1≤i≤j≤n,所需要的最少数乘次数m[i, j],则原问题的最优值为m[1,n]。
问题的关键点就在于在哪处进行分割,找出分割点k,然后根据下面公式可以计算出结果:
当i=j时,A[i: j]=Ai,因此,m[i, i]=0,i=1,2,…,n
当i<j 时,m[i,j] = m[i,k] + m[k+1,j] + p(i-1)*p(k)*p(j)

代码如下:
import java.util.Scanner;

public class JuZhenMulti {
	/**
	 * 矩阵连乘问题
	 * @param p 
	 * @param s 
	 * @param m 
	 */
	
	static void MatrixChain(int n, int[] p, int[][] m, int[][] s) {
		int r,i,j,k,q=0;
		
		for(i=1;i<=n;i++)
	        m[i][i] = 0;
		
		//r为矩阵链的长度

	    // r=2时,计算 m[i,i+1],i=1,2,...,n-1 (长度r=2的链的最小代价)
		for (r = 2; r <= n; r++) {
			for (i = 1; i <= n-r+1; i++) {
				//以i为起始位置,j为长度为r的链的末位
				j=i+r-1;
				m[i][j]=100000000;/*m[i+1][j]+p[i-1]*p[i]*p[j];*/
				//s[i][j]=i;
				 //k从i到j-1,以k为位置划分
	            for(k=i;k<=j-1;k++)
	            {
	                q=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
	                if(q<m[i][j])
	                {
	                    m[i][j]=q;
	                    s[i][j]=k;
	                }
	            }
			}
		}
		
		System.out.println(m[1][n]);
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in=new Scanner(System.in);
		//n为矩阵个数
		int n=in.nextInt();
		int N=n+1;
		int m[][] = new int[N][N];
		int s[][] = new int[N][N];
		
		int x=0;
		//设置一维数组p用来存放矩阵链,p[0],p[1]为第一个矩阵的行数和列数;p[1]、p[2]为第二个矩阵的行、列数。。。
		int p[] = new int[N];
		for (int i = 0; i < n; i++) {
			p[i] = in.nextInt();
			x=in.nextInt();
		}
		p[n] = x;
		
		MatrixChain(n,p,m,s);
		
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值