poj1179 环形+区间dp

因为要用到模,所以左起点设置为0比较好

#include<iostream>
#include<cstdio>
#include<cstring>
#define INF 0x3f3f3f3f
using namespace std;
char c[55];
int val[55],dp_max[55][55],dp_min[55][55];
int cal(char x,int a,int b){if(x=='t')return a+b;return a*b;}

int main(){
    int n;
    while(scanf("%d",&n)==1){
        for(int i=0;i<n;i++) cin>>c[i]>>val[i];
        for(int i=0;i<n;i++) dp_min[i][i]=dp_max[i][i]=val[i];//长度为1的情况
        for(int len=1;len<n;len++)
            for(int l=0;l<n;l++){//枚举左端点 
                int MAX=-INF,MIN=INF; 
                int r=(l+len)%n;    
                for(int k=0;k<len;k++){
                    int p1=(l+k)%n,p2=(l+k+1)%n;
                    MAX=max(MAX,cal(c[p2],dp_max[l][p1],dp_max[p2][r]));
                    MAX=max(MAX,cal(c[p2],dp_min[l][p1],dp_min[p2][r]));
                    MIN=min(MIN,cal(c[p2],dp_max[l][p1],dp_max[p2][r]));
                    MIN=min(MIN,cal(c[p2],dp_min[l][p1],dp_min[p2][r]));
                }
                dp_max[l][r]=MAX;
                dp_min[l][r]=MIN;
            }
        int ans=-INF;
        for(int l=0;l<n;l++){
            int r=(l+n-1)%n;
            ans=max(ans,dp_max[l][r]);
        }     
        printf("%d
",ans);
        for(int l=0;l<n;l++){
            int r=(l+n-1)%n;
            if(dp_max[l][r]==ans) printf("%d ",l+1);
        }
        puts("");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zsben991126/p/10222172.html