zoukankan      html  css  js  c++  java
  • 洛谷 P4342 [IOI1998]Polygon(区间DP)

    题目链接:https://www.luogu.com.cn/problem/P4342

    考虑断掉哪条边,可以将区间变成环,然后进行区间DP。

    因为数据有负数,而两个负数(最小值)相乘可能是最大值,或者正数乘负数可能是最小值等情况。所以要保存最大值和最小值。

    所以设f[i][j][0/1]表示[i,j]区间所能求得的最大/小值。DP后用ans记录长度为n的最大值。然后再扫一遍,如果有长度为n的最大值等于ans,则将i都输出。

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 int n;
     5 const int N=105;
     6 char op[N];
     7 int a[N];
     8 int f[N][N][2],ans;
     9 int main(){
    10     scanf("%d",&n);
    11     for(int i=1;i<=n;i++){
    12         cin>>op[i]>>a[i];
    13         a[i+n]=a[i]; op[i+n]=op[i];
    14     }
    15     for(int i=1;i<=2*n;i++)
    16     for(int j=1;j<=2*n;j++) f[i][j][0]=-0x3f3f3f3f,f[i][j][1]=0x3f3f3f3f;
    17     for(int i=1;i<=2*n;i++) f[i][i][0]=f[i][i][1]=a[i];
    18     for(int l=1;l<=n;l++)
    19     for(int i=1;i<=2*n;i++){
    20         int j=i+l;
    21         if(j>2*n) break;
    22         for(int k=i+1;k<=j;k++){
    23             if(op[k]=='x'){
    24                 f[i][j][0]=max(f[i][j][0],max(f[i][k-1][0]*f[k][j][0],f[i][k-1][1]*f[k][j][1]));
    25                 f[i][j][1]=min(f[i][j][1],min(f[i][k-1][0]*f[k][j][1],min(f[i][k-1][1]*f[k][j][0],f[i][k-1][1]*f[k][j][1])));
    26             }
    27             else{
    28                 f[i][j][0]=max(f[i][j][0],f[i][k-1][0]+f[k][j][0]);
    29                 f[i][j][1]=min(f[i][j][1],f[i][k-1][1]+f[k][j][1]);
    30             }
    31         }
    32     }
    33     for(int i=1;i<=n;i++) ans=max(ans,f[i][i+n-1][0]); printf("%d
    ",ans);
    34     for(int i=1;i<=n;i++) if(f[i][i+n-1][0]==ans) printf("%d ",i);
    35     return 0;
    36 }
    AC代码
  • 相关阅读:
    我心飞翔
    又见草堂
    有一种爱只能用心去珍藏《转贴》
    人事管理制度(爆笑)
    廊桥放歌
    记住: 惰性,职业生涯的无形杀手
    职场“三无人员”如何突破自己
    升职“流产”,都是谦虚惹的祸(转)
    李嘉诚让员工忠诚的简单办法
    尤未尽意
  • 原文地址:https://www.cnblogs.com/New-ljx/p/13701781.html
Copyright © 2011-2022 走看看