一道警钟一样的好题
解析
乍一看:
“这不就能量项链嘛,这也蓝?”
然后就愉快的WA掉了…
qwq
让我们回归本源,在什么时候可以动态规划?
“局部最优解可以带动全局最优解的时候,我们可以使用动态规划算法”
然而在本题中,却不满足这个条件!
局部的最大值不一定会导致全局的最优!
当另一边为负时,局部取最大反而是最差的结果
所以应该维护一个最小值,考虑从两方面进行转移
以后写类似的题一定要多想一想,不能想当然
代码
#include<bits/stdc++.h>
using namespace std;
const int N=120;
const int mod=1e9+7;
double eps=1e-10;
#define ll long long
ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();};while(isdigit(c)){x=x*10+c-'0';c=getchar();};return x*f;
}int n,m;int x[N],op[N];
int mx[N][N],mn[N][N];
//1: add 2:multiply
int q[N],num;
int main(){memset(mx,-0x3f,sizeof(mx));memset(mn,0x3f,sizeof(mn));n=read();for(int i=1;i<=n;i++){char c;scanf(" %c%d",&c,&x[i]);op[i]=c=='t'?1:2;}for(int i=n+1;i<=2*n;i++){x[i]=x[i-n];op[i]=op[i-n];}for(int i=1;i<=n*2;i++) mn[i][i]=mx[i][i]=x[i];for(int len=2;len<=n;len++){for(int l=1;l+len-1<=2*n;l++){int r=l+len-1;for(int i=l;i<r;i++){if(op[i+1]==1){mx[l][r]=max(mx[l][r],mx[l][i]+mx[i+1][r]);mn[l][r]=min(mn[l][r],mn[l][i]+mn[i+1][r]);}else{mx[l][r]=max(mx[l][r],max(mx[l][i]*mx[i+1][r],mn[l][i]*mn[i+1][r]));mn[l][r]=min(mn[l][r],min(mx[l][i]*mx[i+1][r],mn[l][i]*mn[i+1][r]));}}}}int ans(-2e9);for(int i=1;i<=n;i++){int o=mx[i][i+n-1];if(ans<o){ans=o;q[num=1]=i;}else if(ans==o) q[++num]=i;}printf("%d\n",ans);for(int i=1;i<=num;i++) printf("%d ",q[i]);return 0;
}
/*
2 2 1
1 1
2 1 1
*/