• 括号匹配问题 区间DP经典问题


    题目链接 http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=15

    给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
    如:
    []是匹配的
    ([])[]是匹配的
    ((]是不匹配的
    ([)]是不匹配的

    分析:要求要添加多少个,可以求出最大匹配的长度,这样剩下的都是没有匹配的,所以每个对于一个匹配就可以了。

    即 答案 = 字符串长度 - 最大匹配长度。

    首先考虑怎么样定义dp让它满足具有通过子结构来求解、

    定义dp [ i ] [ j ] 为串中第 i 个到第 j 个括号的最大匹配数目

    那么我们假如知道了 i 到 j 区间的最大匹配,那么i+1到 j+1区间的是不是就可以很简单的得到。

    那么 假如第 i 个和第 j 个是一对匹配的括号那么dp [ i ] [ j ] = dp [ i+1 ] [ j-1 ] + 2 ;

    那么我们只需要从小到大枚举所有 i 和 j 中间的括号数目,然后满足匹配就用上面式子dp,然后每次更新dp [ i ] [ j ]为最大值即可。

    更新最大值的方法是枚举 i 和 j 的中间值,然后让 dp[ i ] [ j ] = max ( dp [ i ] [ j ] , dp [ i ] [ f ] + dp [ f+1 ] [ j ] ) ;

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <string>
     5 #include <algorithm>
     6 using namespace std;
     7 #define maxn 110
     8 int N, dp[maxn][maxn];
     9 string s;
    10 int main(){
    11     scanf("%d", &N);
    12     
    13     while(N--){
    14         memset(dp, 0, sizeof(dp));
    15         cin>>s;
    16         for(int len = 1; len < s.size(); len++){
    17             for(int i = 0, j = len; j < s.size(); i++,j++){
    18                 if(s[i] == '(' && s[j] == ')' || s[i] == '[' && s[j] == ']')
    19                     dp[i][j] = dp[i+1][j-1] + 2;
    20                 for(int k = i; k < j; k++)
    21                     dp[i][j] = max(dp[i][j] , dp[i][k] + dp[k][j]);
    22             }
    23         }
    24         printf("%d
    ", s.size()-dp[0][s.size()-1]);
    25         
    26     }
    27     
    28     return 0;
    29 }

    类似题 POJ 2955   http://poj.org/problem?id=2955

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <string>
     5 #include <algorithm>
     6 using namespace std;
     7 #define maxn 110
     8 int N, dp[maxn][maxn];
     9 string s;
    10 int main(){
    11     while(cin>>s){
    12         if(s == "end") break;
    13         memset(dp, 0, sizeof(dp));
    14         
    15         for(int len = 1; len < s.size(); len++){
    16             for(int i = 0, j = len; j < s.size(); i++,j++){
    17                 if(s[i] == '(' && s[j] == ')' || s[i] == '[' && s[j] == ']')
    18                     dp[i][j] = dp[i+1][j-1] + 2;
    19                 for(int k = i; k < j; k++)
    20                     dp[i][j] = max(dp[i][j] , dp[i][k] + dp[k][j]);
    21             }
    22         }
    23         printf("%d
    ", dp[0][s.size()-1]);
    24         
    25     }
    26     
    27     return 0;
    28 }
  • 相关阅读:
    Qt之QLineEdit
    Redis与Java
    Qt之属性系统
    Qt之Meta-Object系统
    设计模式(八)外观模式
    Qt之QRadioButton
    Qt之QSystemTrayIcon
    Redis与Java
    JSP公用COMMON文件
    eclipse远程调试Tomcat方法[转]
  • 原文地址:https://www.cnblogs.com/titicia/p/4345018.html
Copyright © 2020-2023  润新知