zoukankan      html  css  js  c++  java
  • 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;
    
    } 
  • 相关阅读:
    【Linux】Ubuntu 安装 openjdk8
    【算法】二分查找
    【算法】大规模排序
    【算法】小规模排序
    【算法】递归
    【数据结构】队列
    【Java】Windows 安装 JDK-13 并配置环境变量
    【数据库】关于 mysql 的执行顺序
    【数据结构】栈
    【数据结构】链表
  • 原文地址:https://www.cnblogs.com/Hilda/p/2939695.html
Copyright © 2011-2022 走看看