洛谷 P4342 [IOI1998]Polygon
题目传送门
解题思路:
一道环形dp,只不过有个地方要注意,因为有乘法,两个负数相乘是正数,所以最小的数是负数,乘起来可能比最大值大,所以要记录最小值(这道题是紫题的原因).
AC代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 5 using namespace std; 6 7 int n,a[110],maxf[110][110],minf[110][110],ans = -2147418364; 8 char c[110]; 9 10 int main() 11 { 12 scanf("%d",&n); 13 for(int i = 1;i <= n; i++) { 14 cin >> c[i] >> a[i];//char和string最好用cin,因为用了scanf调了好长时间 15 a[i+n] = a[i]; 16 c[i+n] = c[i]; 17 } 18 memset(minf,0x80,sizeof(minf));//最小值 19 memset(maxf,0x3f,sizeof(maxf));//最大值 20 for(int i = 1;i <= n + n - 1; i++) { 21 maxf[i][i] = a[i]; 22 minf[i][i] = a[i]; 23 } 24 for(int p = 2;p <= n; p++) 25 for(int i = 1;i + p - 1 <= n + n - 1; i++){ 26 int j = i + p - 1; 27 for(int k = i + 1;k <= j; k++) 28 if(c[k] == 'x') {//如果是乘 29 minf[i][j] = max(minf[i][j],max(minf[i][k-1] * minf[k][j],max(maxf[i][k-1] * minf[k][j],max(minf[i][k-1] * maxf[k][j],maxf[i][k-1] * maxf[k][j])))); 30 maxf[i][j] = min(maxf[i][j],min(minf[i][k-1] * minf[k][j],min(maxf[i][k-1] * minf[k][j],min(minf[i][k-1] * maxf[k][j],maxf[i][k-1] * maxf[k][j])))); 31 } 32 else { 33 minf[i][j] = max(minf[i][j],minf[i][k-1] + minf[k][j]); 34 maxf[i][j] = min(maxf[i][j],maxf[i][k-1] + maxf[k][j]); 35 } 36 } 37 for(int i = 1;i <= n; i++) 38 ans = max(ans,minf[i][i+n-1]); 39 printf("%d\n",ans); 40 for(int i = 1;i <= n; i++) 41 if(minf[i][i+n-1] == ans) 42 printf("%d ",i); 43 return 0; 44 }