DP训练 CDOJ1321柱爷的恋爱 [区间dp]

2 篇文章 0 订阅

此题原本为我下午准备讲课的题,居然。。。10分钟ac

这运气。。。果真我cdoj做多了。

括号匹配 (parenthesis.pas/cpp/c)

【题目描述】
给出长度为N的括号序列(只包含(,),[,]),问有多少种方法删掉这些括号的一个子集,使得剩下的括号序列是合法的,请注意不能全部删完。
【输入格式】
输入的第一行是一个整数N,表示序列的长度。
接下来一行N个字符,表示括号序列。
【输出格式】
一行,表示方案数模1000000007的结果。
【样例输入】
4
()[]
【样例输出】
3
【数据范围】
30%的数据保证:1 <= N <= 20。
100%的数据保证:1 <= N <= 300。

思考

裸的区间DP,
1.当 i==j dp[i][j]=1 ;
2当i!=j&&i,k为一对匹配括号, dp[i][j]=res+dp[i+1][k1]+dp[k+1][j] ;
3其他情况 dp[i][j]=dp[i+1][j] ;

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char s[305];
long long dp[305][305];
long long dfs(long long i,long long j){
    if(dp[i][j]>=0)return dp[i][j];
    if(i>=j)return 1;
    long long res=dfs(i+1,j);
    char rt='0';
    if(s[i]=='(')rt=')';
    else if(s[i]=='[')rt=']';
    if(rt!='0')
        for(long long q=i+1;q<=j;q++)if(s[q]==rt)
                res=max(res,res+dfs(i+1,q-1) *dfs(q+1,j))%1000000007;
    dp[i][j]=res;
    return res%1000000007;
}
int main(){
//  freopen("parenthesis.in","r",stdin);
//  freopen("parenthesis.out","w",stdout);
    long long n;  
    cin>>n;
    for(register long long i=0;i<=n;i++)
        for(register long long j=0;j<=n;j++)dp[i][j]=-1;
    cin>>s;  
    long long ans=((dfs(0,n-1)%1000000007-1)%1000000007+1000000007)%1000000007;  
    cout<<ans<<endl;  
    return 0;
}

//
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值