poj1179 环形+区间dp

时间:2023-03-10 00:13:48
poj1179 环形+区间dp

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

#include<iostream>
#include<cstdio>
#include<cstring>
#define INF 0x3f3f3f3f
using namespace std;
char c[];
int val[],dp_max[][],dp_min[][];
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)==){
for(int i=;i<n;i++) cin>>c[i]>>val[i];
for(int i=;i<n;i++) dp_min[i][i]=dp_max[i][i]=val[i];//长度为1的情况
for(int len=;len<n;len++)
for(int l=;l<n;l++){//枚举左端点
int MAX=-INF,MIN=INF;
int r=(l+len)%n;
for(int k=;k<len;k++){
int p1=(l+k)%n,p2=(l+k+)%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=;l<n;l++){
int r=(l+n-)%n;
ans=max(ans,dp_max[l][r]);
}
printf("%d\n",ans);
for(int l=;l<n;l++){
int r=(l+n-)%n;
if(dp_max[l][r]==ans) printf("%d ",l+);
}
puts("");
}
return ;
}