poj 1179 Polygon

来源:互联网 发布:乐视2pro如何备份数据 编辑:程序博客网 时间:2024/06/08 13:08

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

思路:区间dp,石子归并的变形。考虑到最大值可能由最小值*最小值转化过来,所以不仅要记录最大值也要记录最小值。

代码

#include<cstdio>#include<algorithm>#include<iostream>#include<vector>using namespace std;const int N=55;const int INF=1<<30;int main(){    int n;    while(scanf("%d",&n)!=EOF)    {int a[N];char  t[2*N];    int dpmax[2*N][2*N],dpmin[2*N][2*N];    //dpmax[i][j]表示 i到j区间内的最大值,dpmin[i][j]表示i到j区间内的最小是    for(int i=1;i<=n;i++)        {            scanf(" %c%d",&t[i-1],&a[i]);            dpmax[i][i]=dpmin[i][i]=a[i];         }    for(int i=1;i<=n;i++)        dpmax[i+n][i+n]=dpmin[i+n][i+n]=a[i];    for(int i=0;i<n;i++)        t[i+n]=t[i];    for(int L=2;L<=n;L++)    {        for(int i=1;i<=2*n-L+1;i++)        {            int j=i+L-1;            dpmax[i][j]=-INF;dpmin[i][j]=INF;            for(int k=i;k<j;k++)            {                if(t[k]=='t')                {                    dpmax[i][j]=max(dpmax[i][j],dpmax[i][k]+dpmax[k+1][j]);                    dpmin[i][j]=min(dpmin[i][j],dpmin[i][k]+dpmin[k+1][j]);                }                else                {                    dpmax[i][j]=max(dpmax[i][j],dpmax[i][k]*dpmax[k+1][j]);                    dpmax[i][j]=max(dpmax[i][j],dpmin[i][k]*dpmin[k+1][j]);                    dpmin[i][j]=min(dpmin[i][j],dpmin[i][k]*dpmin[k+1][j]);                    dpmin[i][j]=min(dpmin[i][j],dpmin[i][k]*dpmax[k+1][j]);                    dpmin[i][j]=min(dpmin[i][j],dpmax[i][k]*dpmin[k+1][j]);                    dpmin[i][j]=min(dpmin[i][j],dpmax[i][k]*dpmax[k+1][j]);                }            }        }    }    int res=-INF;    for(int i=1;i<=n;i++)        res=max(res,dpmax[i][i+n-1]);    printf("%d\n",res);    int flag=0;    for(int i=1;i<=n;i++)    {        if(res==dpmax[i][i+n-1])        {            if(flag) printf(" ");flag=1;            printf("%d",i);        }    }    printf("\n");    }    return 0;}
1 0
原创粉丝点击