算法分析第八次作业

1. 问题

  给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2 ,…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。

2. 解析

     这其实是个很简单的问题,区间dp模板题,dp[i][j],表示区间i到j合并的最小值,枚举k表示分割点,dp[1][n]即为答案

 转移方程:dp[i][j]=min(dp[i][j],dp[i][k]+d[k+1][j]+b[i]*b[k+1]*b[j+1]

3. 设计

  

for (int h = 1; h < n; h++) {//区间dp 
	for (int i = 1; i <= n - h; i++) {
		int j = i + h;
		for (int k = i; k <= j - 1; k++) {
			if(dp[i][j]==0) dp[i][j]=dp[i][k] + dp[k + 1][j] + b[i] * b[k + 1] * b[j + 1];
			else dp[i][j]=min(dp[i][j],dp[i][k] + dp[k + 1][j] + b[i] * b[k + 1] * b[j + 1]);
		}
	}
}

 

 

4. 分析

 复杂度 O(n3)

5. 源码

https://github.com/Tinkerllt/algorithm-work.git

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<set>
#include<deque>
#include<queue>
#include<vector>
//#include<unordered_map>
#include<map>
#include<stack>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define Pii pair<ll,int>
#define m_p make_pair
#define l_b lower_bound
#define u_b upper_bound 
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const int maxn = 600 + 11;
const int maxm = 600 + 11;
const int mod = 1e9 + 7;
const double eps = 1e-5;
ll rd() { ll x = 0, f = 1; char ch = getchar(); while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }return x * f; }
inline ll qpow(ll a, ll b, ll p) { ll res = 1; while (b) { if (b & 1) { res *= a; res %= p; }b >>= 1; a = a * a%p; }return res; }
inline ll gcd(ll a, ll b) { if (b == 0) return a; return gcd(b, a%b); }
//iterator 
//head
//priority_queue
int b[maxn], dp[maxn][maxn],a[maxn];
int main() {
	int n;
	memset(dp, 0, sizeof dp);
	cin >> n;
	cin >> b[1] >> b[2];
	for (int i = 3; i <= n + 1; i++) {
		cin >> a[i] >> b[i];
	}
	for (int h = 1; h < n; h++) {//区间dp 
		for (int i = 1; i <= n - h; i++) {
			int j = i + h;
			for (int k = i; k <= j - 1; k++) {
				if(dp[i][j]==0) dp[i][j]=dp[i][k] + dp[k + 1][j] + b[i] * b[k + 1] * b[j + 1];
				else dp[i][j]=min(dp[i][j],dp[i][k] + dp[k + 1][j] + b[i] * b[k + 1] * b[j + 1]);
			}
		}
	}
	cout << dp[1][n] << endl;
	return 0;
}

 

posted @ 2020-04-21 15:36  Tinker1998  阅读(80)  评论(0编辑  收藏  举报