基本方法:
首先,确认能否容易地得到简单情况的解?然后,假设规模为N-1的情况已经得到解。最后,重点分析:当规模扩大到N时,如何枚举出所有的情况,并且要确保对于每一种子情况都能用已经得到的数据解决。
正确分类,要包含不重复的所有情况
编程中的空间换时间的思想,并不一定只是从N-1到N的分析
错排问题
错排式
基本形式:d[1]=0; d[2]=1
递归式:d[n]= (n-1)( d[n-1] + d[n-2]) 通项公式:
卡特兰数
公式:
设h(n)为catalan数的第n项,令h(0)=1,h(1)=1,catalan数满足
递推式:
h(n)= h(0)h(n-1)+h(1)h(n-2) + … + h(n-1)h(0) (n≥2)
h(n)=h(n-1)(4n-2)/(n+1)
递推关系的解为:
h(n)=C(2n,n)/(n+1) (n=0,1,2,…)
递推关系的另类解为:
h(n)=C(2n,n) - C(2n,n-1) (n=0,1,2,…) //理解:翻折思想 https://blog.youkuaiyun.com/qq_30115697/article/details/88906534
特征:都能找到一个点,将该问题分成两个同样性质的子问题
引例:
-
HDOJ小兔的棋盘(此题另一种分析,根据递推的思路,到每个点只能是通过它左边和下面的点走到的,故到该点的走法数t[i][j]=t[i-1] [j]+t[i] [j-1]
-
Games of Connections
应用:
-
n对括号的合法配对方案书
矩阵连乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案。( h(n) 种)
-
n个节点的二叉树的形态数
-
n+1个叶子(n个非叶节点)的满二叉树的形态数, 走到左儿子+1,走到 右儿子-1,类似于括号匹配
-
n个数入栈后出栈的排列总数
一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列?
分析:
设 f(n)=序列个数为n的出栈序列种数。假定,最后出栈的元素为k,显然,k取不同值时的情况是相互独立的,也就是求出每种k最后出栈的情况数后可用加法原则,由于k最后出栈,因此,在k入栈之前,比k小的值均出栈,此处情况有f(k-1)种,而之后比k大的值入栈,且都在k之前出栈,因此有f(n-k)种方式,由于比k小和比k大的值入栈出栈情况是相互独立的,此处可用乘法原则,f(n-k)*f(k-1)种,求和便是Catalan递归式。
首次出空之前第一个出栈的序数k将1n的序列分成两个序列,其中一个是1k-1,序列个数为k-1,另外一个是k+1~n,序列个数是n-k。
此时,我们若把k视为确定一个序数,那么根据乘法原理,f(n)的问题就等价于——序列个数为k-1的出栈序列种数乘以序列个数为n - k的出栈序列种数,即选择k这个序数的 f(n) =f(k-1) × f(n-k)。而k可以选1到n,所以再根据加法原理,将k取不同值的序列种数相加,得到的总序列种数为:f(n) = f(0)f(n-1) + f(1)f(n-2) + …… + f(n-1)f(0)。
类似问题:买票问题。 有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少种方法使得只要有10元的人买票,售票处就有5元的钞票找零(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈)
-
对凸n+2边形进行不同的三角形分割的方案数(分割线断点仅为顶点,且分割线仅在顶点上相交)
类似问题:小兔的棋盘、 在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数
-
n层的阶梯切割为n个矩形的切法数
前几项:1,1,2,5,14,42,132,429,1430……(注意,如果是前30项能用long long存储,40项之后long long型的数组也存不下了)
例题
HDOJ统计问题