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;
    }
    

      

  • 相关阅读:
    ZEat
    BingWallpaper
    ZBreak
    C语言块内变量回收问题
    Android 隐藏RadoiButton左边按钮
    php文件管理与基础功能的实现
    Ajax写分页查询(实现不刷新页面)
    jquery写日期选择器
    ajax三级联动下拉菜单
    ajax bookstrap美化网页,并实现页面的加载,删除与查看详情
  • 原文地址:https://www.cnblogs.com/z1141000271/p/6721398.html
Copyright © 2011-2022 走看看