poj1179多边形——区间DP

题目:http://poj.org/problem?id=1179

区间DP,值得注意的是有负值,而且有乘法,因此可能会影响最大值;

注意memset中写-1仅仅是-1,-2才是一个很小的负数;

最后找mxx时也要注意可能最大是负值,因此不能随便给mxx赋成0或-1之类。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,a[105],mx[105][105],mn[105][105],ans[105],t,INF=40000;
bool sid[105][105];
int main()
{
    char dc;
    scanf("%d ",&n);
    memset(mx,-2,sizeof mx);//-1仅是-1! 
    memset(mn,1,sizeof mn);
    for(int i=1;i<=n;i++)
    {
        if(i==n)scanf("%c %d",&dc,&a[i]);
        else scanf("%c %d ",&dc,&a[i]);
        if(dc=='t')sid[i-1][i]=1;
        else sid[i-1][i]=0;
        a[i+n]=a[i];
        sid[i-1+n][i+n]=sid[i-1][i];
        mx[i][i]=a[i];mx[i+n][i+n]=a[i];
        mn[i][i]=a[i];mn[i+n][i+n]=a[i];
    }
    for(int l=2;l<=n;l++)
        for(int i=1;i<=n*2-l;i++)//
        {
            int j=i+l-1;
            for(int k=i;k<j;k++)
            {
                if(sid[k][k+1])
                {
                    mx[i][j]=max(mx[i][j],mx[i][k]+mx[k+1][j]);
                    mn[i][j]=min(mn[i][j],mn[i][k]+mn[k+1][j]);
                }
                else
                {
                    mx[i][j]=max(mx[i][j],mx[i][k]*mx[k+1][j]);
                    mx[i][j]=max(mx[i][j],mn[i][k]*mn[k+1][j]);
                    mx[i][j]=max(mx[i][j],mx[i][k]*mn[k+1][j]);
                    mx[i][j]=max(mx[i][j],mn[i][k]*mx[k+1][j]);
                    
                    mn[i][j]=min(mn[i][j],mx[i][k]*mx[k+1][j]);
                    mn[i][j]=min(mn[i][j],mn[i][k]*mn[k+1][j]);
                    mn[i][j]=min(mn[i][j],mx[i][k]*mn[k+1][j]);
                    mn[i][j]=min(mn[i][j],mn[i][k]*mx[k+1][j]);
                }
            }
        }
    int mxx=-INF;//!-1
//    for(int i=1;i<=n;i++)
//    {
//        if(mx[i][i+n-1]>mxx)
//        {
//            memset(ans,0,sizeof ans);
//            t=1;
//            ans[t]=i;
//            mxx=mx[i][i+n-1];
//        }
//        else if(mx[i][i+n-1]==mxx)ans[++t]=i;
//    }
//    printf("%d\n",mxx);
//    for(int i=1;i<=t;i++)
//        printf("%d ",ans[i]);
    for(int i=1;i<=n;i++)
        mxx=max(mxx,mx[i][i+n-1]);
    printf("%d\n",mxx);
    for(int i=1;i<=n;i++)
        if(mx[i][i+n-1]==mxx)
            printf("%d ",i);
    return 0;
}

 

posted @ 2018-03-15 23:53  Zinn  阅读(134)  评论(0编辑  收藏  举报