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;
}

 

posted on 2018-03-15 22:42  Narh  阅读(96)  评论(0编辑  收藏  举报

导航