zoukankan      html  css  js  c++  java
  • 洛谷P4342/poj1179 Polygon

    看到这种拆边成链的问题,第一反应就是区间dp.

    这一题的难点在状态转移上。单纯储存最大值不能满足dp中最优子结构的性质。

    从转移角度入手,发现最大值的来源可能是两个最大值相加,相乘,两个最小值的相乘(不过把这个最小值相乘的去掉好像对答案没有什么影响);

    最小值的来源可能是两个最小值相加,相乘,或者最大值和最小值相乘(正负得负)。

    根据这个想法,不难想出用 f[ i ][ j ][ 0 / 1 ]储存从 i 到 j 的最大值与最小值.

    最后,把链拆开复制一倍,跑一下区间dp就可以在O(N3)的时间内求出答案了!

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 using namespace std;
     6 const int MAXN = 55;
     7 const int INF = 0x3f3f3f3f;
     8 
     9 int N;
    10 int f[MAXN * 2][MAXN * 2][2];//1->max, 0->min
    11 int W[MAXN * 2], opt[MAXN * 2];
    12 //opt : 1.opt[i]->opt between i and i + 1;
    13 //        2.0->'+', 1->'*';
    14 
    15 
    16 int main()
    17 {
    18     //freopen("p4342.in", "r", stdin);
    19     scanf("%d", &N);
    20 
    21     char ch;
    22     for(int i = 1; i <= N * 2; i++)
    23     {
    24         if(i % 2 == 1)
    25         {
    26             scanf(" %c", &ch);
    27             opt[i / 2] = ch == 'x';
    28         }
    29         else
    30             scanf(" %d", &W[i / 2]);
    31     }
    32 
    33     for(int i = N + 1; i <= 2 * (N + 1); i++)
    34     {
    35         W[i] = W[i - N];
    36         opt[i - 1] = opt[i - N - 1];
    37     }
    38 
    39     //for(int i = 1; i <= 2 * N; i++)
    40     //    cout<<W[i]<<" ";
    41 
    42     for(int i = 1; i <= 2 * N; i++)
    43         for(int j = 1; j <= 2 * N; j++)
    44             f[i][j][0] = INF, f[i][j][1] = -INF;
    45 
    46     for(int i = 1; i <= 2 * N; i++)
    47         f[i][i][1] = f[i][i][0] = W[i];
    48 
    49     for(int len = 2; len <= N; len++)
    50         for(int l = 1; l <= (2 * N - len + 1); l++)
    51         {
    52             int r = l + len - 1;
    53             for(int k = l; k < r; k++)
    54             {
    55                 if(opt[k] == 1)
    56                 {
    57                     f[l][r][0] = min(f[l][k][0] * f[k + 1][r][1], f[l][r][0]);
    58                     f[l][r][0] = min(f[l][k][1] * f[k + 1][r][0], f[l][r][0]);
    59                     f[l][r][0] = min(f[l][k][0] * f[k + 1][r][0], f[l][r][0]);
    60                     f[l][r][0] = min(f[l][k][1] * f[k + 1][r][1], f[l][r][0]);
    61 
    62                     f[l][r][1] = max(f[l][k][0] * f[k + 1][r][0], f[l][r][1]);
    63                     f[l][r][1] = max(f[l][k][1] * f[k + 1][r][1], f[l][r][1]);
    64                 }
    65                 else
    66                 {
    67                     f[l][r][0] = min(f[l][k][0] + f[k + 1][r][0], f[l][r][0]);
    68                     f[l][r][1] = max(f[l][k][1] + f[k + 1][r][1], f[l][r][1]);
    69                 }
    70             }
    71         }
    72                 
    73 
    74     int ans = -INF;
    75     for(int i = 1; i <= N; i++)
    76         ans = max(ans, f[i][i + N - 1][1]);
    77     cout<<ans<<endl;
    78     for(int i = 1; i <= N; i++)
    79         if(f[i][i + N - 1][1] == ans)
    80             cout<<i<<" ";
    81     return 0;
    82 }
  • 相关阅读:
    Maven创建项目: Failed to execute goal org.apache.maven.plugin( mvn archetype:create)
    maven仓库--私服(Nexus的配置使用)
    maven仓库--私服(Nexus的配置使用)
    maven仓库--私服(Nexus的配置使用)
    maven中snapshot快照库和release发布库的区别和作用
    maven中snapshot快照库和release发布库的区别和作用
    maven中snapshot快照库和release发布库的区别和作用
    Bugzilla使用手册及解决方案
    jQuery常见的几个文档处理方式
    正则表达式实现对多个表格的某一指定字段的样式添加
  • 原文地址:https://www.cnblogs.com/wsmrxc/p/9028828.html
Copyright © 2011-2022 走看看