标签:comm 区间dp blog 思路 选择 ... 输出 决定 str
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; }
标签:comm 区间dp blog 思路 选择 ... 输出 决定 str
原文地址:http://www.cnblogs.com/zhumengdexiaobai/p/7608236.html