------------只要够努力,人生最坏的结局不过是大器晚成!!!

                  C时间限制:3000 毫秒 |  C内存限制:3000 Kb
题目内容:
 n个矩阵A1,A2,...,An, ,如果其维度分别为d0xd1, d1xd2, ...dn-1xdn,则可以进行连乘运算A1A2A3..An . 
连乘运算可以采取不同的顺序进行,如(A1A2)A3 和 A1(A2A3),这两种顺序的消耗乘法计算量是不同的,前者是
d0.d1.d2+d0.d2.d3,后者d0.d1.d3+d1.d2.d3.

第1步选择哪两个,第2步又选择哪两个,一直到最后算出结果需要做n-1次决定。其中有一种计算顺序使得
A1A2A3..An总的乘法计算量最小。
输入描述
第一行输入n
第二行输入维度向量d0,d1,...dn

输出描述
输出所需的最少乘法次数。

输入样例
4
2 3 2 4 3

输出样例
48
思路: 区间dp, 设dp[i][j]表示第i个矩阵到第j个矩阵之间合并的最少相乘次数
则递归方程为: dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + d[i-1]*d[k]*d[j]); i < k < j;
需要知道相邻矩阵的乘法规则:A1(x1, y1)* A2(x2, y2) = x1 * y1 * y2;(x表示行,y表示列)
#include <iostream>
using namespace std;
int dp[100][100];
int a[100];
int n;

int fun(int i, int j){
	if(i == j)
		return dp[i][j];
	if(i == j - 1)
		return dp[i][j] = a[i - 1] * a[i] * a[j];
	if(i < j - 1){
		dp[i][j] = 10000000;
		for(int k = i + 1; k < j; k++)
			dp[i][j] = min(dp[i][j], fun(i, k) + fun(k + 1, j) + a[i - 1] * a[j] * a[k]);
	}
	return dp[i][j];
}

int main(){
	cin >> n;
	
	for(int i = 0; i <= n; i++)
		cin >> a[i];
	cout << fun(1, n);
	
	return 0;
}

 

posted on 2017-09-28 19:51  ystraw  阅读(289)  评论(0编辑  收藏  举报

不经一番切孤寒,怎得梅花扑鼻香