京东笔试:括号匹配 ---- 逆向思维题

一模一样的题 !!!
http://www.cnblogs.com/tbt123/p/6920729.html

题目:有一个合法的字符串,合法是指左括号与右括号全部能配对,现在每次将这个序列第一个左括号删去,在将任意一个右括号删去,每次删去后的序列必须合法,求有多少种方法,答案对10000000007。

输入:

一个合法括号序列。

输出:

方案数。

样例1:

Input:

()()()()

Output:

1

样例2:

Input

(((())))()()

Output:

24

首先我们很容易知道如果模拟的话很复杂,在进一步思考会发现从左到右走会有后效性,当前所选的右括号会决定序列是否合法且影响到下一次的选择,既然有后效性,那就倒过来,从右往左

可以证明到右边先选不会影响到左边。

附上简易的证明过程:首先明确左括号是能跟任意一个其右边的右括号匹配的,假设当前从右向左走到某一个左括号,右边的左括号已经全部满足了,左边的左括号也是能够满足,因为当前剩下的右括号全部在右边,也就是说现在任意选择一个右边的右括号与当前走到的左括号匹配都能保证剩余的右括号能与其左边的左括号匹配,即不会影响到整个序列的合法性。

定义一个ans记录方案数(这里有个坑,ans初始值为1!!!),再定义一个tot记录现在右边剩余的右括号,初始值为0,遇到右括号就加1,遇到左括号就减1。思路很清晰了,代码很容易写出。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
const long long mod=10000000007ll;
char A[20000005];
long long ans=1;
int tot;
int main()
{

    freopen("ka.in","r",stdin);
    freopen("ka.out","w",stdout);
    scanf("%s",A);
    int len=strlen(A);
    for(int i=len-1;i>=0;i--)
    {
        if(A[i]==')')tot++;
        else if(A[i]=='('){
            ans=(ans*tot)%mod;
            tot--;
        }
    }
    printf("%I64d",ans);
    //printf("%lld",ans);
     return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值