Acwing P283 多边形 题解

Analysis

总体来说是一个区间DP

此题首先是一个环,要你进行删边操作,剩下的在经过运算得到一个最大值

注意事项:

1.删去一条边,剩下的构成一条线,相当于求此的最大值,经典区间DP该有的样子;

2.现在大概想法有了,还有一个细节,就是当中会出现负数,负数*负数是可能超过当前的最大值的,所以我们不仅需要维护区间最大值,还有最小值,因为两个极小值相乘是可以超过最大值的。

 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define int long long  6 #define maxn 50+10 7 #define INF 9223372036854775807 8 using namespace std; 9 inline int read()  10 { 11 int x=0; 12 bool f=1; 13 char c=getchar(); 14 for(; !isdigit(c); c=getchar()) if(c==-) f=0; 15 for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-0; 16 if(f) return x; 17 return 0-x; 18 } 19 inline void write(int x) 20 { 21 if(x<0){putchar(-);x=-x;} 22 if(x>9)write(x/10); 23 putchar(x%10+0); 24 } 25 int n; 26 int sym[2*maxn],num[2*maxn]; 27 int dp[maxn][2*maxn][2*maxn],mdp[maxn][2*maxn][2*maxn]; 28 int ans; 29 inline int max_five(int a,int b,int c,int d,int e) 30 { 31 return max(max(max(a,b),max(c,d)),e); 32 } 33 inline int min_five(int a,int b,int c,int d,int e) 34 { 35 return min(min(min(a,b),min(c,d)),e); 36 } 37 inline void clear() 38 { 39 for(int i=1;i<=50;i++) 40  { 41 for(int j=1;j<=100;j++) 42  { 43 for(int k=1;k<=100;k++) 44  { 45 dp[i][j][k]=-INF; 46 mdp[i][j][k]=INF; 47  } 48  } 49  } 50 } 51 signed main() 52 { 53 // freopen("ploygon.in","r",stdin); 54 // freopen("ploygon.out","w",stdout); 55  clear(); 56 n=read(); 57 for(int i=1;i<=2*n;i++) 58  { 59 if(i%2==1)  60  { 61 char in; 62 cin>>in; 63 if(in==t) sym[i/2+1]=1; 64 else if(in==x) sym[i/2+1]=2; 65  } 66 else if(i%2==0) num[i/2]=read(); 67  } 68 for(int i=n+1;i<=2*n;i++)  69  { 70 sym[i]=sym[i-n]; 71 num[i]=num[i-n]; 72  } 73 for(int j=1;j<=n;j++) 74  { 75 for(int i=1;i<=2*n;i++) 76  { 77 dp[j][i][i]=num[i]; 78 mdp[j][i][i]=num[i]; 79  } 80  } 81 for(int i=1;i<=n;i++)  82  { 83 for(int len=2;len<=n;len++) 84  { 85 for(int j=i;j<=i+n-1;j++) 86  { 87 int k=j+len-1; 88 if(k>=i+n) break; 89 for(int l=j;l<k;l++) 90  { 91 if(sym[l+1]==1) 92  { 93 dp[i][j][k]=max(dp[i][j][k],dp[i][j][l]+dp[i][l+1][k]); 94 mdp[i][j][k]=min(mdp[i][j][k],mdp[i][j][l]+mdp[i][l+1][k]); 95  }  96 else if(sym[l+1]==2)  97  { 98 dp[i][j][k]=max_five(dp[i][j][k],dp[i][j][l]*dp[i][l+1][k],mdp[i][j][l]*dp[i][l+1][k],dp[i][j][l]*mdp[i][l+1][k],mdp[i][j][l]*mdp[i][l+1][k]); 99 mdp[i][j][k]=min_five(dp[i][j][k],dp[i][j][l]*dp[i][l+1][k],mdp[i][j][l]*dp[i][l+1][k],dp[i][j][l]*mdp[i][l+1][k],mdp[i][j][l]*mdp[i][l+1][k]);100  }101  }102  }103  }104 ans=max(ans,dp[i][i][i+n-1]);105  }106  write(ans);107 printf("\n");108 for(int k=1;k<=n;k++)109  {110 if(dp[k][k][k+n-1]==ans)111  {112  write(k);113 printf(" ");114  }115  }116 return 0;117 }

请各位大佬斧正(反正我不认识斧正是什么意思)

相关文章