标签:label hat enc algo field www. div \n http
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions:6633 | Accepted: 2834 |
Description
Input
Output
Sample Input
4 t -7 t 4 x 2 x 5
Sample Output
33 1 2
Source
题意:
给一个n个顶点n条边的多边形,顶点上有一个整数值,边上有一个字符表示+ 或者 *。首先删除一条边,然后每次对两个顶点进行合并,用一个顶点代替这两个顶点,顶点的值是这两个顶点运算的结果,运算符为连接这两个顶点的边。最后只剩下一个顶点,问这个顶点最大值会是多少,以及得到这个结果的删边方法。
思路:
删除了一条边后,就类似于石子合并(https://www.cnblogs.com/wyboooo/p/9757387.html)这道题了。
不同之处在于因为有负数和乘法的存在,最大值有可能是由两个最小值相乘得到的。因此需要同时记录最大值和最小值。【已经遇到好多有负数、乘法要记录最大值最小值的问题了,需要注意!】
最开始需要枚举删掉的边,一个好方法是,将原来的数组在末尾复制一遍。从1~n跑一遍成为枚举,最后找dp[i][i+n-1]的最大值就行了。
这种“任意选择一个位置断开,复制形成2倍长度的链”的方法,是解决DP中环形结构的常用手段之一。
1 //#include <bits/stdc++.h> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<stdio.h> 6 #include<cstring> 7 #include<map> 8 9 #define inf 0x3f3f3f3f 10 using namespace std; 11 typedef long long LL; 12 13 int n; 14 const int maxn = 55; 15 int num[maxn * 2]; 16 char op[maxn * 2]; 17 int dp[maxn * 2][maxn * 2][2]; 18 19 int main() 20 { 21 while(scanf("%d", &n) != EOF){ 22 23 for(int i = 1; i <= n; i++){ 24 scanf(" %c %d", &op[i], &num[i]); 25 } 26 for(int i = n + 1; i <= 2 * n; i++){ 27 op[i] = op[i - n]; 28 num[i] = num[i - n]; 29 } 30 for(int i = 0; i <= n * 2; i++){ 31 dp[i][i][0] = dp[i][i][1] = num[i]; 32 for(int j = i + 1; j <= 2 * n; j++){ 33 dp[i][j][0] = -inf; 34 dp[i][j][1] = inf; 35 } 36 } 37 38 for(int len = 2; len <= n; len++){ 39 for(int l = 1; l <= 2 * n - len + 1; l++){ 40 int r = l + len - 1; 41 for(int k = l; k < r; k++){ 42 43 int res1, res2; 44 if(op[k + 1] == ‘t‘){ 45 res1 = dp[l][k][0] + dp[k + 1][r][0]; 46 res2 = dp[l][k][1] + dp[k + 1][r][1]; 47 } 48 else{ 49 res1 = dp[l][k][0] * dp[k + 1][r][0]; 50 res2 = dp[l][k][1] * dp[k + 1][r][1]; 51 dp[l][r][0] = max(dp[l][r][0], dp[l][k][1] * dp[k + 1][r][1]); 52 dp[l][r][1] = min(dp[l][r][1], dp[l][k][0] * dp[k + 1][r][1]); 53 dp[l][r][1] = min(dp[l][r][1], dp[l][k][1] * dp[k + 1][r][0]); 54 } 55 dp[l][r][0] = max(dp[l][r][0], res1); 56 dp[l][r][1] = min(dp[l][r][1], res2); 57 } 58 } 59 } 60 61 int ans = -inf; 62 for(int i = 1; i <= n; i++){ 63 ans = max(dp[i][i + n - 1][0], ans); 64 } 65 printf("%d\n", ans); 66 bool flag = false; 67 for(int i = 1; i <= n; i++){ 68 if(dp[i][i + n - 1][0] != ans)continue; 69 if(flag){ 70 printf(" "); 71 } 72 else{ 73 flag = true; 74 } 75 printf("%d", i); 76 } 77 printf("\n"); 78 } 79 return 0; 80 }
标签:label hat enc algo field www. div \n http
原文地址:https://www.cnblogs.com/wyboooo/p/9757740.html