zoukankan      html  css  js  c++  java
  • poj 2955 Brackets (区间DP)

    题意:

    在一些括号中找到一个序列,里面的括号都两两配对。求序列最长长度。

    dp[i][j]为i~j的最大括号数,考虑第i个括号,有两种情况:

    不管i直接算dp[i][j] = dp[i + 1][j];★

    枚举i+1~j,找到和i匹配的右括号,有dp[i][j] = max(dp[i][j],dp[i + 1][k - 1] + 2 + dp[k + 1][j])。

    递归写法:

     1 #include <cstdio>
     2 #include <cstring>
     3 #define N 105
     4 
     5 int dp[N][N], len, vis[N][N];
     6 char s[N];
     7 
     8 int max2(int x, int y)
     9 {
    10     return x > y ? x : y;
    11 }
    12 
    13 int dfs(int i, int j)
    14 {
    15     if(i>=j || i<1 || j>len) return 0;
    16     if(vis[i][j]==1return dp[i][j];
    17     dp[i][j] = dfs(i+1, j);
    18     if(s[i]=='(')
    19     {
    20         for(int x=i+1; x<=j; x++) //x++写成j++
    21         {
    22             if(s[x]==')')
    23             {
    24                 dp[i][j] = max2(dp[i][j], dfs(i+1,x-1) + dfs(x+1, j) + 2);
    25             }
    26         }
    27     }
    28     else if(s[i]=='[')
    29     {
    30         for(int x=i+1; x<=j; x++)
    31         {
    32             if(s[x]==']')
    33             {
    34                 dp[i][j] = max2(dp[i][j], dfs(i+1,x-1) + dfs(x+1, j) + 2);
    35             }
    36         }
    37     }
    38 
    39     vis[i][j] = 1;
    40     return dp[i][j];
    41 }
    42 
    43 int main()
    44 {
    45     while(scanf("%s",s+1)!=EOF)
    46     {
    47         if(strcmp(s+1,"end")==0)
    48             break;
    49         len = strlen(s+1);
    50         memset(vis, 0sizeof(vis));
    51         memset(dp, 0sizeof(dp));
    52 
    53         dfs(1,len);
    54         printf("%d ",dp[1][len]);
    55     }
    56     return 0;
    57 }
    View Code

     非递归:

     

    dp[i][j] = max(dp[i][x]+dp[x+1][j])  (x:i~j-1)

    if(check(i,j)) dp[i][j] = max(dp[i][j], dp[i+1][j-1]+2);

     1 #include <cstdio>
     2 #include <cstring>
     3 #define N 105
     4 
     5 int dp[N][N];
     6 char s[N];
     7 
     8 int check(int i, int j)
     9 {
    10     if((s[i]=='('&&s[j]==')') || (s[i]=='['&&s[j]==']'))
    11         return 1;
    12     return 0;
    13 }
    14 
    15 int max2(int x, int y)
    16 {
    17     return x > y ? x : y;
    18 }
    19 
    20 int main()
    21 {
    22     while(scanf("%s",s+1)!=EOF)
    23     {
    24         if(strcmp(s+1,"end")==0break;
    25 
    26         int len = strlen(s+1);
    27         memset(dp, 0sizeof(dp));
    28 
    29         if(len>=2)
    30             for(int i=1; i<=len-1; i++) if(check(i,i+1)) dp[i][i+1] = 2;
    31 
    32         for(int k=3; k<=len; k++)
    33         {
    34             for(int i=1; k+i-1<=len; i++)
    35             {
    36                 int j = i + k - 1;
    37                 //dp[i][j] = max2(dp[i+1][j], dp[i][j-1]);
    38                 if(check(i,j)) dp[i][j] = max2(dp[i][j], dp[i+1][j-1] + 2);
    39                 //if(check(i,i+1)) dp[i][j] = max2(dp[i][j], dp[i+2][j] + 2);
    40                 //if(check(j-1,j)) dp[i][j] = max2(dp[i][j], dp[i][j-2] + 2);
    41                 for(int x = i; x<=j-1; x++) //x=i  与  x=i+1  这里WA
    42                     dp[i][j] = max2(dp[i][j],dp[i][x]+dp[x+1][j]);
    43             }
    44         }
    45 
    46         printf("%d ",dp[1][len]);
    47     }
    48     return 0;
    49 }
    View Code

    WA

     1、状态方程不全

     2、for()内写错。

  • 相关阅读:
    【译文】不是所有的 bug 都值得修复的
    11月第5周业务风控关注|重磅!瓜子二手车“遥遥领先”被罚天价1250万
    AutoCAD .NET二次开发(四)
    AutoCAD .NET二次开发(三)
    ArcGIS10.2下调试10.1的程序
    再遇1402,注册表权限问题
    ArcGIS Add-in——自动保存编辑
    只打开一个子窗体
    获取编辑器两种方法
    Adobe Acrobat Pro 11安装激活
  • 原文地址:https://www.cnblogs.com/byluoluo/p/3561819.html
Copyright © 2011-2022 走看看