POJ 1179 Polygon

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

1》给出的样例,取得的最优值为去掉2边后结果为:4*2*5-7=33

2》对于加法两个最优的相加肯定是最优的,但是对于乘法:

       

求最大值:

正数X正数

两个都是最大的

结果最大

 

正数X负数

正数最小,负数最大

结果最大

 

负数X负数

两个都是最小值

结果最大

求最小值:

正数X正数

两个都是最小值

结果最小

 

正数X负数

正数最大,负数最小

结果最小

 

负数X负数

两个都最大

结果最小

要保存子问题的最大值和最小值,还具有点最优子结构,可以用动态规划求解。

fmin(i, L)表示以i为首,顺时针长度为L的链的计算结果最小值。

fmax(i, L)表示以i为首,顺时针长度为L的链的计算结果最大值。

然后枚举t(0<=t<L),求出区间的最大值or最小值

fmin={ fmin(i, t)+fmin((i+t)%n+1, L-t-1 }  ,当opr((i+t-1)%n==’+’ 

     min{fmin(i, t) +fmin(i+t)%n+1, L-t-1 )

          fmin(i, t)+fmax(i+t)%n+1, L-t-1)

          fmax(i, t)+fmax(i+t)%n+1, L-t-1)

          fmax(i, t)+fmin(i+t)%n+1, L-t-1)

         }  ,当opr((i+t-1)%n==*

fmax={fmax(i, t)+fmax((i+t)%n+1, L-t-1) },当opr((i+t-1)%n==’+’

      Max{ fmin(i, t) +fmin(i+t)%n+1, L-t-1 )

          fmin(i, t)+fmax(i+t)%n+1, L-t-1)

          fmax(i, t)+fmax(i+t)%n+1, L-t-1)

          fmax(i, t)+fmin(i+t)%n+1, L-t-1)

         }  ,当opr((i+t-1)%n==*

3》初始化fmin(i, 0) = num[i], fmax(i, 0)=num[i];

代码如下:

View Code
/*

POJ 1179 多边形计算

*/

#include<iostream>

#include<string.h>

using namespace std;

#define N 105

int main()

{

    int i, L, t, minnum, maxnum, mm, n;

    int fmax[N][N], fmin[N][N], num[N], pos[N];

    char opr[N];

    while(cin>>n)

    {

        for(i=0; i<n; i++)

            cin>>opr[i]>>num[i];

        for(i=0; i<n; i++)

            fmax[i][0]=num[i], fmin[i][0]=num[i];

        for(L=1; L<n; L++) //长度

            for(i=0; i<n; i++)

            {

                fmax[i][L]=-65535;

                fmin[i][L]=65535;

                for(t=0; t<L; t++)

                {

                    if(opr[(i+t+1)%n]=='t')

                    {

                        minnum=fmin[i][t]+fmin[(i+t+1)%n][L-1-t];

                        maxnum=fmax[i][t]+fmax[(i+t+1)%n][L-1-t];

                        if(fmin[i][L]>minnum)   fmin[i][L]=minnum;

                        if(fmax[i][L]<maxnum)   fmax[i][L]=maxnum;

                    }

                    if(opr[(i+t+1)%n]=='x')

                    {

                        mm=fmin[i][t]*fmin[(i+t+1)%n][L-t-1];

                        if(fmin[i][L]>mm)    fmin[i][L]=mm;

                        if(fmax[i][L]<mm)    fmax[i][L]=mm;

                        mm=fmin[i][t]*fmax[(i+t+1)%n][L-t-1];

                        if(fmin[i][L]>mm)    fmin[i][L]=mm;

                        if(fmax[i][L]<mm)    fmax[i][L]=mm;

                        mm=fmax[i][t]*fmax[(i+t+1)%n][L-t-1];

                        if(fmin[i][L]>mm)    fmin[i][L]=mm;

                        if(fmax[i][L]<mm)    fmax[i][L]=mm;

                        mm=fmax[i][t]*fmin[(i+t+1)%n][L-t-1];

                        if(fmin[i][L]>mm)    fmin[i][L]=mm;

                        if(fmax[i][L]<mm)    fmax[i][L]=mm;

                    }

                }

            }

        mm=fmax[0][n-1];

        for(i=1; i<n; i++)

            if(mm<fmax[i][n-1])

                mm=fmax[i][n-1];

        cout<<mm<<endl;

        int flag=0;

        for(i=0; i<n; i++)

            if(mm==fmax[i][n-1])

                pos[flag++]=i%n+1;

        for(i=0; i<flag; i++)

        {

            cout<<pos[i];

            if(i<flag-1)

                cout<<" ";

        }

        cout<<endl;

    }

    return 0;

} 

 

posted on 2013-03-02 09:45  crying_Dream  阅读(370)  评论(0编辑  收藏  举报