LA 6892 The Safe Secret(矩阵连乘)

https://vjudge.net/problem/UVALive-6892

题意:

给出n个数字和n个符号(+,-,*和?),?可以为+,-,*中任意一个,现在要计算出这个式子的最小值和最大值,并且运算顺序随意,也就是可以随便加括号。之后进行旋转之后继续计算。比如一开始给的是1 ? 5 + 0 ? -2 - -3 *,那么旋转之后就是上面的第二行了,这样一共需要旋转n次,也就是说要计算n次。

思路:
运算顺序随意,有没有感觉很像矩阵连乘?

这道题目就是升级版的矩阵连乘吧。

因为是可以旋转的,那么就在后面再加一行变成线性。

之后就和矩阵连乘的做法差不多了,用两个数组来保存,一个保存最大值,另一个最小值即可。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<sstream>
 6 #include<vector>
 7 #include<stack>
 8 #include<queue>
 9 #include<cmath>
10 #include<map>
11 using namespace std;
12 typedef long long ll;
13 typedef pair<int,long long> pll;
14 const ll INF = 1LL<<60;
15 const int maxn=500+5;
16 
17 int n;
18 ll f[maxn][maxn];
19 ll g[maxn][maxn];
20 char op[maxn];
21 
22 int main()
23 {
24     //freopen("input.txt","r",stdin);
25     while(~scanf("%d",&n))
26     {
27         for(int i=1;i<=2*n;i++)
28         for(int j=1;j<=2*n;j++)
29         {
30             f[i][j]=-INF;
31             g[i][j]=INF;
32         }
33 
34         for(int i=1;i<=n;i++)
35         {
36             scanf("%lld %c",&f[i][i],&op[i]);
37             f[n+i][n+i]=f[i][i];
38             g[i][i]=g[n+i][n+i]=f[i][i];
39             op[n+i]=op[i];
40         }
41 
42         for(int r=2;r<=n;r++)
43         {
44             for(int i=1;i<=2*n-r+1;i++)
45             {
46                 int j=i+r-1;
47                 for(int k=i;k<j;k++)
48                 {
49                     if(op[k]=='+'||op[k]=='?')
50                     {
51                         f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]);
52                         g[i][j]=min(g[i][j],g[i][k]+g[k+1][j]);
53                     }
54 
55                     if(op[k]=='-'||op[k]=='?')
56                     {
57                         f[i][j]=max(f[i][j],f[i][k]-g[k+1][j]);
58                         g[i][j]=min(g[i][j],g[i][k]-f[k+1][j]);
59                     }
60 
61                     if(op[k]=='*'||op[k]=='?')
62                     {
63                         f[i][j]=max(f[i][j],f[i][k]*f[k+1][j]);
64                         f[i][j]=max(f[i][j],g[i][k]*g[k+1][j]);
65                         f[i][j]=max(f[i][j],f[i][k]*g[k+1][j]);
66                         f[i][j]=max(f[i][j],g[i][k]*f[k+1][j]);
67 
68                         g[i][j]=min(g[i][j],f[i][k]*f[k+1][j]);
69                         g[i][j]=min(g[i][j],g[i][k]*g[k+1][j]);
70                         g[i][j]=min(g[i][j],f[i][k]*g[k+1][j]);
71                         g[i][j]=min(g[i][j],g[i][k]*f[k+1][j]);
72                     }
73                 }
74             }
75         }
76         for(int i=1;i<=n;i++)
77         {
78             printf("%lld%lld",abs(g[i][i+n-1]),abs(f[i][i+n-1]));
79         }
80         printf("
");
81     }
82     return 0;
83 }
原文地址:https://www.cnblogs.com/zyb993963526/p/6955199.html