蓝桥杯b组(括号序列)

1.题目要求添加尽量少的括号,使之变成有效的括号序列  形如:(())

2.通过分析题意我们可以,大概模拟出三种括号的情况,如:((())--->左括号大于右括号且,(()))--->右括号大于左括号,))(((--->无一括号配对。

3.我们对其中的一种情况进行分析如:右括号大于左括号的情况 "(( )))",那么我们只需要添加左括号即可,通过在不同的右括号前添加 '(' 可以达到去重的效果

使用动态规划的做法就是dp[i][j],其中i代表第i个括号,j代表左括号比右括号多的个数,dp[i][j]代表第i个括号前左括号比右括号多j个的方案数,初始条件dp[0][0]=1

于是推出状态转移方程 当第i个字符为左括号时---->dp[i][j]=dp[i-1][j-1],

当第i个字符为右括号时dp[i][j]=dp[i-1][j+1]+dp[i-1][j]因为多添加了一个')'所以前i个字符中左括号因该比右括号多j+1个,+dp[i-1][j]

是因为如果我们在该 ')' 前添加一个 '(' 那么只需要dp[i-1][j]即可,因为抵消掉了一个 ')'

由于我们没办法判断题目输入会给出哪一种情况,于是我们把左括号和右括号的数量对换再算一次,假设第一次算出的是正确答案,第二次由于左括号始终大于右括号所以不断添加左括号也无法使其变成有效序列只能使原括号序列的情况为1

如是第三种情况  ))((( 相当于分开算使 ))变成合法序列的方案数乘以使(((变成合法括号序列的方案数,将 '('  ')' 的数量反转刚好可以求出各自的值

代码如下:

#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const ll N=1e9+7;
char s[5001];
ll dp[5001][5001];
void dp_s(int len){
  memset(dp,0,sizeof dp);
  dp[0][0]=1;
  for(int i=1;i<=len;i++){
    if(s[i]=='('){
      for(int j=1;j<=len;j++){
        dp[i][j]=dp[i-1][j-1];
      }
    }else{
      dp[i][0]=(dp[i-1][1]+dp[i-1][0])%N;//防止溢出
      for(int j=1;j<=len;j++){
        dp[i][j]=(dp[i-1][j+1]+dp[i][j-1])%N;
      }
    }
  }
}
int main(){
  scanf("%s",s+1);
  int len=strlen(s+1);
  ll ret1=0,ret2=0;
  dp_s(len);
  for(int i=0;i<=len;i++){
    if(dp[len][i]){
      ret1+=dp[len][i];//遇到第一个满足的就break
      break;
    }
  }
  int a=1,b=len;
  while(a<b){
    char temp=s[a];
    s[a]=s[b];
    s[b]=temp;
    a++;
    b--;
  }
  for(int i=1;i<=len;i++){
    if(s[i]=='(')s[i]=')';
    else s[i]='(';
  }//将数量对换
  dp_s(len);
  for(int i=0;i<=len;i++){
    if(dp[len][i]){
      ret2+=dp[len][i];//遇到第一个满足的就break
      break;
    }
  }
  cout<<ret2*ret1%N;
  return 0;
}

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值