卡特兰数:
设h(n)为卡特兰数的第n项, 令h(0)=1,h(1)=1,则满足
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,…)
简单应用:
一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列?
设f(n)=序列个数为n的出栈序列种数,最后出栈的元素为k。当k值不同时,情况相互独立。所以当k取一个值是,出栈种 数为f(k-1)f(n-k),则f(n)= f(0)f(n-1)+f(1)f(n-2)+……+f(n-1)f(0).
这个式子满足卡特兰数,f(n)=h(n)= C(2n,n)/(n+1)= c(2n,n)-c(2n,n-1)
约瑟夫环:
1、N个人围在一起坐成环状
2、从K开始报数
3、数到M的时候,此人出列,下一个人重新报数
4、一直循环,直到所有人出列,约瑟夫环结束
刚开始是的约瑟夫环记作F(N),N为当前约瑟夫环人数,从第一个人报数的人开始编号,记作0,1,2,3一直到N-1。
当一个人出列的时候,会组成一个新的约瑟夫环F(N-1),重新编号,从第一个人报数的人开始编号,记作0,1,2,3一直到N-2。依次类推下去,直到所有人出列。
F(N)第m次出列的人(N>m)=F(N-1)第m-1次出列的人=…=F(N-m+1)第1次出列的人,就是F(N-m+1)编号为M-1的人
求F(N)第m次出列的人,就是求F(N-m+1)编号为M-1的人在F(N)中的编号。根据F(N)生成F(N-1)这样的例子,易得:
F(N)中的编号 = (F(N-1)中的编号+M)%N(N>1)
int ysf(int sum, int value, int n) {
if (n == 1)
return (sum + value - 1) % sum;
else
return (ysf(sum - 1, value, n - 1) + value) % sum;
}
Sum为N
Value为M
N为第m次
如果不求中间过程,只看结果的话
int ysf1(int sum, int value) {
if (sum == 1)
return 0;
else
return (ysf1(sum - 1, value) + value) % sum;
}