hdu4828卡特兰数

题目大意:有2行N列的长方形格子,把1到2N这些数放进格子里面,使每行每列都递增。

思路:1到2n个数一次放进格子,类比一个模型,如果这个数放上一行,相当于进栈,如果放下一行,相当于出栈,

也就是相当于,n个0和n个1排序,要求每个点的前面都要求0的个数大于等于1的个数,问排列的顺序的种数。

可以转换为卡特兰数,有递推式 cn+1=(4n+2)/(n+2)cn;

具体卡特兰数的资料:http://blog.csdn.net/ocgcn2010/article/details/42930289

要用到逆元


#include <iostream>
#include <cmath>
#include <stdio.h>
#include <algorithm>
#include <ctime>
using namespace std;
#define LL long long
#define ULL unsigned long long
//#define REP(i,n) for(int i=0;i<n;++i)
#define REP(i,a,b) for(int i=a;i<=b;++i)
#define maxn 1000010
#define mset(a) memset(a,0,sizeof a)
#define FR(a) freopen(a,"r",stdin)
#define FW(a) freopen(a,"w",stdout)
const LL MOD=1000000007;
LL Catalan[maxn];
void gcd(LL a,LL b,LL &d, LL &x,LL &y)
{
	if(!b){d=a;x=1;y=0;return;}
	gcd(b,a%b,d,y,x);
	y-=(a/b)*x;
}
LL inv(LL a)
{
	LL x,y,d;
	gcd(a,MOD,d,x,y);
	return d==1?((x%MOD+MOD)%MOD):-1;
}
void init()
{
	Catalan[1]=1;
	Catalan[2]=2;
	REP(i,2,maxn-3)
	{
		LL temp=(4*i+2)*Catalan[i]%MOD;
		Catalan[i+1]=temp*inv(i+2)%MOD;
	}
}
int main()
{
	init();
	int t;
	cin>>t;
	REP(c,1,t)
	{
		printf("Case #%d:\n",c);
		int n;
		scanf("%d",&n);
		printf("%I64d\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(2)=h(0)*h(1)+h(1)*h(0)=1*1+1*1=2
h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0)=1*2+1*1+2*1=5
另类递推式 [2]  :
h(n)=h(n-1)*(4*n-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,...)


你可能感兴趣的:(hdu4828卡特兰数)