POJ1179 Polygon
题目:http://poj.org/problem?id=1179
石子合并的升级版。有负值。但运算符只有 + 和 * 。
考虑负值对原做法正确性的影响:之所以仅记录最大值可能不对,是因为有可能负数 * 负数得到很大结果。
发现只有这种情况影响。而且这种情况中负数越小越优。所以记录一下最小值,每次参与更新就行了。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; //const int INF=16843009,FIN=-16843010; int n,d[2][110][110],ans=-32730;//别忘了ans的初值 char ch[55]; int main() { scanf("%d",&n);//初值? memset(d[0],-2,sizeof d[0]); memset(d[1],1,sizeof d[1]); for(int i=1;i<=n;i++) { scanf(" %c%d",&ch[i],&d[0][i][i]); d[1][i][i]=d[0][i][i]; d[1][i+n][i+n]=d[1][i][i];d[0][i+n][i+n]=d[0][i][i]; ch[i+n]=ch[i]; // printf("(%d)(%c)",d[0][i][i],ch[i]); } for(int i=2;i<=n;i++) for(int l=1;l<=2*n-i;l++) { int r=l+i-1; for(int k=l;k<r;k++)//l~k k+1~r { if(ch[k+1]=='t') { // printf("(%d+%d) ",d[0][k][k],d[0][k+1][k+1]); d[0][l][r]=max(d[0][l][r],d[0][l][k]+d[0][k+1][r]); d[1][l][r]=min(d[1][l][r],d[1][l][k]+d[1][k+1][r]); } if(ch[k+1]=='x') { // printf("(%d*%d) ",d[0][k][k],d[0][k+1][k+1]); d[0][l][r]=max(d[0][l][r],max(d[0][l][k]*d[0][k+1][r],d[1][l][k]*d[1][k+1][r])); d[1][l][r]=min(min(d[1][l][r],d[1][l][k]*d[1][k+1][r]) ,min(d[0][l][k]*d[1][k+1][r],d[1][l][k]*d[0][k+1][r])); } } } for(int i=1;i<=n;i++) ans=max(ans,d[0][i][i+n-1]); printf("%d\n",ans); for(int i=1;i<=n;i++) if(d[0][i][i+n-1]==ans) printf("%d ",i); return 0; }