题目: LINK
【HDU 5184 Brackets (卡特兰数)】题意: 定义合法的括号序列如下:
● 空序列是合法括号序列
● 如果s是一个合法括号序列,那么(s)也是合法括号序列
● 如果a和b是合法括号序列,那么ab也是合法括号序列
● 没有其它情况是合法括号序列
给定已知括号序列的前一部分,问可以构造出多少合法序列。
可以提前判断出一些非法的情况,比如n为奇数,给定部分括号非法。之后求合法学列数量。
其实就是求出卡特兰数。
结果ans = C(a+b, b) - C(a+b, b-1) , (设a=剩余要填的')'的数量, b=剩余要填的'('的数量)
-------------------------
关于卡特兰数,一个例子是有n个1,m个-1(n>=m),要求用这些1和-1排列形成n+m长度的排列,要求前i项的和sum[i]>=0 (1<=i<=n+m),这个排列的方案数目就是卡特兰数。方案数应该是C(n+m, m) - C(n+m, m-1)
可以看出本题和上面的例子很相像。当然这只是卡特兰数的一个例子,应该还有好多用途。
关于上面结果的证明过程:可以转化为在平面坐标系中,从(0, 0)走到(n, m)每次向上走或者向右走,且不能越过x=y的直线的方法数。把(0, 0) 和(n, m)都往下移一个单位成为(0, -1), (n, m-1). 从(0, 0)走到(n, m)的非法数目 = (0, -1)到(n, m-1)过程中至少一点和x=y相交的走法数。ans = 总数目 - 非法数目 = C(n+m, m) - 非法数目。根据对称性,(0, -1)到(n, m-1)过程中至少一点和x=y相交的走法数 = (-1, 0)到(n, m-1)的方法数。所以ans = C(n+m, m) - C(n+m, m-1)。
-------------------------
回到原题,原题结果的求法同样放到坐标系中去,合法序列数目为(x, y) ==> (m, m)且不越过x=y的数目,x为已有'('的数目,y为已有')'的数目,m = n/2;
通过平移和对称性,我们可以转化为求(0, 0) ==> (m-y, m-x)不越过x=y直线的方法数,就可以利用上面求出的公式。
会用到有除法的取模,所以要求出逆元。
/* ***********************************************
Author: Napoleon
Mail: tyfdream@163.com
Created Time: 2015-03-11 16:04:59
Problem: CB_32_C.cpp
************************************************ */
#include
#include
#include
#include
#include
#include
#include
#include
#include
推荐阅读
- AIoT(人工智能+物联网)|程序员的数学【线性代数基础】
- topcoder|Topcoder SRM 661 Div1 Easy: MissingLCM
- 高斯消元
- 水题纪念|【51nod - 1098】 最小方差(基础数学,公式化简,前缀和,积的前缀和)
- 扩展欧几里德算法(gcd扩展使用)
- 数学|CF 514D.Nature Reserve 几何,二分,交集
- codeforces|Codeforces Round #665 (Div. 2) C. Mere Array(数学)
- codeforces|Codeforces Round #665 (Div. 2) A. Distance and Axis(思维,数学)
- 数论|Codeforces Global Round 10 B. Omkar and Infinity Clock(数学)