算法分析设计实践——矩阵链乘法

问题:

设N个矩阵序列,其中第i个矩阵式p[i - 1] * p[i]阶矩阵,给定矩阵的向量P,求一种乘法次序,使得基本运算总次数最小

解析:

设A[i][j] 为 ∏jk = ia[k]

设cnt[i][j]为A[i][j]的最少运算次数

cnt[i][j] = min(cnt[i][k] + cnt[k + 1][j] + p[i - 1] * p[k] * p[j])

设计(核心代码):

 1     for (int len = 2; len <= n; ++len)
 2     {
 3         for (int i = 1; i + len - 1 <= n; ++i)
 4         {
 5             int j = i + len - 1;
 6             cnt[i][j] = inf;
 7             s[i][j] = 0;
 8             for (int k = i; k < j; ++k)
 9             {
10                 int tmp = cnt[i][k] + cnt[k + 1][j] + p[i - 1] * p[k] * p[j];
11                 if (tmp < cnt[i][j])
12                 {
13                     cnt[i][j] = tmp;
14                     s[i][j] = k;
15                 }
16             }
17         }
18     }

分析:

O(n3

源码:

https://github.com/BambooCertain/Algorithm.git

 1 #include<cstdio>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<vector>
 7 #include<queue>
 8 #include<set>
 9 #include<map>
10 #include<cctype>
11 #define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
12 #define mem(a,x) memset(a,x,sizeof(a))
13 #define lson rt<<1,l,mid
14 #define rson rt<<1|1,mid + 1,r
15 #define P pair<int,int>
16 #define ull unsigned long long
17 using namespace std;
18 typedef long long ll;
19 const int maxn = 2e5 + 10;
20 const ll mod = 998244353;
21 const int inf = 0x3f3f3f3f;
22 const long long INF = 0x3f3f3f3f3f3f3f3f;
23 const double eps = 1e-7;
24 
25 inline ll read()
26 {
27     ll X = 0, w = 0; char ch = 0;
28     while (!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
29     while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
30     return w ? -X : X;
31 }
32 
33 int cnt[1000][1000] , s[1000][1000];
34 int p[1000];
35 int n;
36 int main()
37 {
38     n = read();
39     for (int i = 0; i <= n; ++i)
40     {
41         p[i] = read();  cnt[i][i] = 0;
42     }
43     for (int len = 2; len <= n; ++len)
44     {
45         for (int i = 1; i + len - 1 <= n; ++i)
46         {
47             int j = i + len - 1;
48             cnt[i][j] = inf;
49             s[i][j] = 0;
50             for (int k = i; k < j; ++k)
51             {
52                 int tmp = cnt[i][k] + cnt[k + 1][j] + p[i - 1] * p[k] * p[j];
53                 if (tmp < cnt[i][j])
54                 {
55                     cnt[i][j] = tmp;
56                     s[i][j] = k;
57                 }
58             }
59         }
60     }
61     cout << cnt[1][n] << endl;
62     return 0;
63 }
完整代码

猜你喜欢

转载自www.cnblogs.com/DreamACMer/p/12748904.html