• UESCTC-2016dp专题 D 柱爷的恋爱


                                               柱爷的恋爱

    Time Limit: 1000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)

    题目链接

    http://acm.uestc.edu.cn/#/contest/show/96

    Description

    她手里有刚刚收到从远方的括号序列(仅包含( ) [ ]的序列),然而序列已经是一团乱麻,不堪入目,柱爷看到她坐在位子掩面哭泣,便上前安慰一番,她向柱爷提出自己的"无理"申请.

    她"蛮横"地要求柱爷计算出:删去这个括号序列的一个子集(不可以把整个括号序列都删去,那可是她的心爱之物;可以不完全删;子集可能是不连续的;子集可能为∅),使得这个括号序列合法的方案数.

    这个方案数可能很大,所以她只要求柱爷计算出这个方案数%1000000007就好了(她心疼柱爷,不想让柱爷打高精度).

    你能帮柱爷解决这个恋爱中的小小问题吗?

    Input

    第一行一个整数NN,表示括号序列的长度

    接下来一行包含一个长度为NN的括号序列字符串

    数据保证:

    • 1N3001≤N≤300

    Output

    一个正整数,表示柱爷要回答她的数.

    Sample input and output

    Sample InputSample Output
    4
    ()[]
    3
    3
    ())
    2

    Hint

    合法的括号序列定义如下:

    • 如果S是合法序列,那(S)和[S]也是合法序列;
    • 如果A和B都是合法序列,那么AB也是合法序列.
    • 例如,下面的字符串都是合法序列:
    • (), [], (()), ([]), ()[], ()[()]

    题意

     给你一个字符序列,对他进行删除操作,可以不删,但不能全删,问最后得到合法序列的删除方法数

    思路

    区间dp,定义dp[l][r]为处理完[l,r]区间后得到的合法序列的个数,考虑转移方程,可由两个状态转移而来:

    1.删除第l个括号,则此时dp[l][r]=dp[l+1][r]

    2.不删除第l个括号,则需要在后面枚举与其配对的括号,将两个区间分别操作,将结果相乘即可。

    注意不要爆int了。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    using namespace std;
    const int maxn=300+7;
    const int mod=1000000007;
    int n;
    string s;
    long long int dp[maxn][maxn];
    
    bool match(int l,int r)  //匹配括号
    {
        if((s[l]=='('&&s[r]==')')||(s[l]=='['&&s[r]==']'))
            return true;
        return false;
    }
    long long int dfs(int l,int r)
    {
        if(~dp[l][r]) return dp[l][r];
        long long int &ans=dp[l][r]=0;
        if(l>r) return ans=1;
        if(l==r) return ans=1;
        ans=dfs(l+1,r);   //删除括号
        ans%=mod;
        for(int i=l;i<=r;i++){   //枚举配对
            if(match(l,i)){
                ans+=dfs(l+1,i-1)*dfs(i+1,r);
                ans%=mod;
            }
        }
        return ans%mod;
    }
    int main()
    {
         scanf("%d",&n);
         cin>>s;
         memset(dp,-1,sizeof(dp));
         long long int ans=(dfs(0,n-1)-1)%mod;
         printf("%lld",ans);
         return 0;
    }
  • 相关阅读:
    【LeetCode每天一题】Rotate List(旋转链表)
    【LeetCode每天一题】Permutation Sequence(排列序列)
    【LeetCode每天一题】Length of Last Word(字符串中最后一个单词的长度)
    【LeetCode每天一题】Merge Intervals(合并区间)
    【LeetCode每天一题】Spiral Matrix II(螺旋数组II)
    Ajax基础
    git的命令行操作
    新闻发布系统之登录和注销
    JSTL和EL
    servlet模板的修改
  • 原文地址:https://www.cnblogs.com/wangdongkai/p/5491661.html
Copyright © 2020-2023  润新知