Codeblock的快捷键说明:
1、按住Ctrl滚滚轮,代码的字体会随你心意变大变小
2、 在编辑区按住右键可拖动代码
3、Ctrl+D可复制当前行或选中块
4、Ctrl+Shift+C注释掉当前行或选中块,Ctrl+Shift+X则解除注释。
5、Tab缩进当前行或选中块,Shift+Tab减少缩进
6、需要更大编辑空间时,F2和Shift+F2分别可以显隐下方Logs & others栏和左方的Management栏
7、Ctrl+PageUp 到达上一个函数,Ctrl+PageDown 到达下一个函数。 • Ctrl+B 添加书签
void *memset(void *s,int ch,size_t n);
函数解释:将 s 中前 n 个字节用 ch 替换并返回 s 。
头文件:#include
//卡特兰数:
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
h(n ) = h(n-1)*(4*n-2) / (n+1)
卡特兰数:规定h(0)=1,而h(1)=1,h(2)=2,h(3)=5,h(4)=14,h(5)=42,h(6)=132,h(7)=429,h(8)=1430,h(9)=4862,h(10)=16796,h(11)=58786,h(12)=208012,h(13)=742900,h(14)=2674440,h(15)=9694845···
1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, …
应用:
1、括号化
矩阵链乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?(h(n-1)种)
f(n) = f(1)*f(n-1) + f(2)*f(n-2) + f(3)*f(n-3) + f(n-1)*f(1)
h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
f(n) = h(n-1) ( n>=3 )(因为h(n)中,n>=2 )
2、出栈次序
一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列?
分析:对于每一个数来说,必须进栈一次、出栈一次。我们把进栈设为状态‘1’,出栈设为状态‘0’。n个数的所有状态对应n个1和n个0组成的2n位二进制数。由于等待入栈的操作数按照1‥n的顺序排列、入栈的操作数b大于等于出栈的操作数a(a≤b),因此输出序列的总数目=由左而右扫描由n个1和n个0组成的2n位二进制数,1的累计数不小于0的累计数的方案种数。
n个数的进栈次序和出栈次序构成了一个含2n个数字的序列。第0个数字肯定是进栈的数,这个数相应的出栈的数一定是第2i+1个数。因为如果是2i,那么中间包含了奇数个数,这奇数个肯定无法构成进栈出栈序列。
设问题的解为f(2n), 那么
f(2n) = f(0)*f(2n-2) + f(2)*f(2n-4) + f(2n-2)*f(0)
f(2n) = h(n)。
类似问题:
n对括号有多少种匹配方式?( h(n) )
3、凸多边形三角划分
在一个凸多边形中,通过若干条互不相交的对角线,把这个多边形划分成了若干个三角形。现在的任务是键盘上输入凸多边形的边数n,求不同划分的方案数f(n)。比如当n=6时,f(6)=14
分析:因为凸多边形的任意一条边必定属于某一个三角形,所以我们以某一条边为基准,以这条边的两个顶点为起点P1和终点Pn(P即Point),将该凸多边形的顶点依序标记为P1、P2、……、Pn,再在该凸多边形中找任意一个不属于这两个点的顶点Pk(2<=k<=n-1),来构成一个三角形,用这个三角形把一个凸多边形划分成两个凸多边形,其中一个凸多边形,是由P1,P2,……,Pk构成的凸k边形(顶点数即是边数),另一个凸多边形,是由Pk,Pk+1,……,Pn构成的凸n-k+1边形。
此时,我们若把Pk视为确定一点,那么根据乘法原理,f(n)的问题就等价于——凸k多边形的划分方案数乘以凸n-k+1多边形的划分方案数,即选择Pk这个顶点的f(n)=f(k)×f(n-k+1)。而k可以选2到n-1,所以再根据加法原理,将k取不同值的划分方案相加,得到的总方案数为:
f(n)=f(2)f(n-2+1)+f(3)f(n-3+1)+……+f(n-1)f(2)。
f(n)=h(n-2) (n=2,3,4,……)。
最后,令f(2)=1,f(3)=1。
思路:以凸多边形的一边为基,设这条边的2个顶点为A和B。从剩余顶点中选1个,可以将凸多边形分成三个部分,中间是一个三角形,左右两边分别是两个凸多边形,然后求解左右两个凸多边形。
设问题的解f(n),其中n表示顶点数,设f(2) = 1,那么f(3) = 1, f(4) = 2, f(5) = 5。f(2)*f(n-1)表示三个相邻的顶点构成一个三角形,那么另外两个部分的顶点数分别为2和n-1。那么
f(n) = f(2)*f(n-1) + f(3)*f(n-2) + ......f(n-2)*f(3) + f(n-1)*f(2)。
f(n) = h(n-2)。
类似问题:
在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数?
思路:以其中一个点为基点,编号为0,然后按顺时针方向将其他点依次编号。那么与编号为0相连点的编号一定是奇数,否则,这两个编号间含有奇数个点,势必会有个点被孤立,即在一条线段的两侧分别有一个孤立点,从而导致两线段相交。设选中的基点为A,与它连接的点为B,那么A和B将所有点分成两个部分,一部分位于A、B的左边,另一部分位于A、B的右边。然后分别对这两部分求解即可。
设问题的解f(n),那么
f(n) = f(0)*f(n-2) + f(2)*f(n-4) + f(4)*f(n-6) + ......f(n-4)*f(2) + f(n-2)*f(0)。
f(0)*f(n-2)表示编号0的点与编号1的点相连,此时位于它们右边的点的个数为0,而位于它们左边的点为2n-2。依次类推。
f(0) = 1, f(2) = 1, f(4) = 2。结合递归式,不难发现
f(2n) =h(n)。
Cn = n*n 的方格地图中,从一个角到另外一个角,不跨越对角线的路径数;
4、给定节点组成二叉树
给定N个节点,能构成多少种不同的二叉树?(能构成h(N)个)(这个公式的下标是从h(0)=1开始的)
思路:可以这样考虑,根肯定会占用一个结点,那么剩余的n-1个结点可以有如下的分配方式,T(0, n-1),T(1, n-2),...T(n-1, 0),设T(i, j)表示根的左子树含i个结点,右子树含j个结点。
设问题的解为f(n),那么
假设f(0) = 1,那么f(1) = 1, f(2) = 2, f(3) = 5。
f(n) = f(0)*f(n-1) + f(1)*f(n-2) + .......+ f(n-2)*f(1) + f(n-1)*f(0)。
f(n) = h(n).
实例:
1、描述:有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?
思路:可以将持5元买票视为进栈,那么持10元买票视为5元的出栈。这个问题就转化成了栈的出栈次序数。由应用2的分析直接得到结果,
f(2n) = h(n)*n!*n!。(后面的*n!*n!为进出栈的排列)
2、拥有 n+1 个叶子节点的二叉树的数量为h(n)
编程实例:
// 使用公式计算:h(n ) = h(n-1)*(4*n-2) / (n+1)
#include
#include
using namespace std;
//h(n ) = h(n-1)*(4*n-2) / (n+1)
int catelan1(int n)
{
if(n==0) return 1;
else return catelan1(n-1)*(4*n-2)/(n+1);
}
//h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
int catelan2(int n)
{
int i,j,h[100];
memset(h, 0, sizeof(h));
h[0]=h[1]=1;
for(i=2; i<=n; i++)
for(j=0; j
h[i] += h[j]*h[i-1-j];
return h[n];
}
//h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
int Cn(int n)
{
int i,sum=1;
for(i=1; i<=n; i++)
sum*=i;
return sum;
}
int catelan3(int n)
{
return Cn(2*n)/Cn(n)/Cn(n)/(n+1);
}
int main()
{
for(int i=0; i<=10; i++)
cout<<"h("<<i<<"):"<<catelan1(i)<<endl;
}
运行结果:
h(0):1
h(1):1
h(2):2
h(3):5
h(4):14
h(5):42
h(6):132
h(7):429
h(8):1430
h(9):4862
h(10):16796
Process returned 0 (0x0) execution time : 0.234 s
Press any key to continue.
公式3有点问题。。。
还有一种分级排列法,没怎么看明白。。。