题目

image-1665644634673
image-1665644646169

题解

1.破环成链,将多边形拓展成一个链,并将这个链拓展一倍,这样就可以得到环中任意两个点的顺序。

2.f[l][r]表示长度从l到r的最大值,选择任意长度段时,可以将其从k处分成两段,那么此时最大值就可以由f[l][k]和f[k+1][r]得到。此时要注意乘法运算,两个大的数相乘不一定是最大的数,因为存在负数,所以要存下当前区间的最小值。

#include<iostream>
using namespace std;
const int N=110,INF=0x3f3f3f3f;
int n;
char c[N];
int w[N],f[N][N],g[N][N];

int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        char op;int x;
        cin>>op>>x;
        c[i]=c[i+n]=op;
        w[i]=w[i+n]=x;
    }
    for(int len=1;len<=n;len++){
        for(int l=1;l+len-1<=2*n;l++){
            int r=l+len-1;
            if(len==1)f[l][r]=g[l][r]=w[l];
            else {
                f[l][r]=-INF,g[l][r]=INF;
                for(int k=l;k<r;k++){
                    char op=c[k+1];
                    int maxl=f[l][k],minl=g[l][k],minr=g[k+1][r],maxr=f[k+1][r];
                    if(op=='t'){
                        f[l][r]=max(f[l][r],maxl+maxr);
                        g[l][r]=min(g[l][r],minl+minr);
                    }else{
                        int x1=maxl*maxr,x2=maxl*minr,x3=minl*maxr,x4=minl*minr;
                        f[l][r]=max(f[l][r],max(max(x1,x2),max(x3,x4)));
                        g[l][r]=min(g[l][r],min(min(x1,x2),min(x3,x4)));
                    }
                }
            }
        }
    }
    int res=-INF;
    for(int i=1;i<=n;i++)res=max(res,f[i][i+n-1]);
    cout<<res<<endl;
    for(int i=1;i<=n;i++){
        if(res==f[i][i+n-1])cout<<i<<" ";
    }
    
    return 0;
}