博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
又是一道水的逆向思维题
阅读量:4707 次
发布时间:2019-06-10

本文共 1172 字,大约阅读时间需要 3 分钟。

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

输入:

一个合法括号序列。

输出:

方案数。

样例1:

Input:

()()()()

Output:

1

样例2:

Input

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

Output:

24

这题水过。。。。。。

首先我们很容易知道如果模拟的话很复杂,在进一步思考会发现从左到右走会有后效性,当前所选的右括号会决定序列是否合法且影响到下一次的选择,既然有后效性,那就倒过来,从右往左!可以证明到右边先选不会影响到左边。(突然想起了一道类似的题,比较复杂,我以后会写的。)附上简易的证明过程:首先明确左括号是能跟任意一个其右边的右括号匹配的,假设当前从右向左走到某一个左括号,右边的左括号已经全部满足了,左边的左括号也是能够满足,因为当前剩下的右括号全部在右边,也就是说现在任意选择一个右边的右括号与当前走到的左括号匹配都能保证剩余的右括号能与其左边的左括号匹配,即不会影响到整个序列的合法性。定义一个ans记录方案数(这里有个坑,ans初始值为1!!!),再定义一个tot记录现在右边剩余的右括号,初始值为0,遇到右括号就加1,遇到左括号就减1。思路很清晰了,代码很容易写出。

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

 博客新手,写的不好的话请谅解>_<!

 

转载于:https://www.cnblogs.com/tbt123/p/6920729.html

你可能感兴趣的文章
maven3在eclipse3.4.2中创建java web项目
查看>>
发布时间 sql语句
查看>>
黑马程序员 ExecuteReader执行查询
查看>>
记一些从数学和程序设计中体会到的思想
查看>>
题目1462:两船载物问题
查看>>
POJ 2378 Tree Cutting(树形DP,水)
查看>>
UVA 116 Unidirectional TSP (白书dp)
查看>>
第三方测速工具
查看>>
数据访问 投票习题
查看>>
cnblog!i'm coming!
查看>>
使用点符号代替溢出的文本
查看>>
fatal: remote origin already exists.
查看>>
LeetCode 242. Valid Anagram
查看>>
JSP表单提交乱码
查看>>
如何适应现代雇佣关系
查看>>
团队项目(第五周)
查看>>
SQL 优化经验总结34条
查看>>
开源 视频会议 收藏
查看>>
核心J2EE模式 - 截取过滤器
查看>>
.net开源CMS
查看>>