zoukankan      html  css  js  c++  java
  • 区间dp 括号匹配问题

    这道题目能用区间dp来解决,是因为一个大区间的括号匹配数是可以由小区间最优化选取得到(也就是满足最优子结构)

    然后构造dp 

    既然是区间类型的dp 一般用二维 我们定义dp[i][j] 表示i~j这个区间需要添加括号的数量

    那么状态怎么转移呢? 

    第一种情况:对于i指向的括号 如果i+1 ~ j里面不存在与之匹配的括号 那么dp[i][j] =dp[i+1][j]+1;

    第二种情况:对于i指向的括号 如果i+1~ j 里面存在与之匹配的括号下标我们记作k 那么在i+1 ~ j 中我们枚举所有的k 

    dp[i][j]=min(dp[i+1][k-1]+dp[k+1][j],dp[i][j]);

    定义好状态转移方程以后 后续的就是合理的对数据填充了 应为dp[i]要用到dp[i+1]的结果 所以我们这里自底向上的遍历

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    using namespace std;
    char s[101];
    bool check(int i,int j)
    {
        if(s[i]=='('&&s[j]==')' || s[i]=='['&&s[j]==']') return true;
        return false;
    }
    int main()
    {
        int n;
        cin>>n;
        while(n--)
        {
            int dp[101][101];
            cin>>s;
            int len=strlen(s);
            memset(dp,0,sizeof(dp));
            for(int i=0;i<len;i++) dp[i][i]=1;
            for(int i=len-2; i>=0; i--)
            {
                for(int j=i; j<len; j++)
                {
                    dp[i][j]=dp[i+1][j]+1;// 第一种情况我们先赋值,由于后续是最小值的比较 所以问题不大
                    for(int k=i+1; k<=j; k++)
                    {
                        if(check(i,k))// 如果匹配
                        {
                            dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k+1][j]);
                        }
                    }
                }
            }
            cout<<dp[0][len-1]<<endl;//
        }
        return 0;
    }
    

      

  • 相关阅读:
    php配置GD库
    Linux 安装 Apache2+php5+gd+freetype2
    gd库
    数组和链表的区别
    python 整数中1出现的次数
    python栈--字符串反转,括号匹配
    Linux基础知识
    操作系统
    后台面试问题
    python 面向对象
  • 原文地址:https://www.cnblogs.com/z1141000271/p/6721398.html
Copyright © 2011-2022 走看看