nyoj 164&&poj2084 Game of Connections 【卡特兰】

本文探讨了卡特兰数在解决排列问题时的应用,通过实例分析和代码实现,详细解释了如何利用卡特兰数计算特定条件下排列的种类数。包括问题背景、分析方法、代码实现及具体例子,旨在深入理解卡特兰数及其在实际问题中的应用。

题意:将1~2n个数依照顺时针排列好。用一条线将两个数字连接起来要求:线之间不能有交点。同一个点仅仅同意被连一次。

最后问给出一个n,有多少种方式满足条件。

分析:

ans[n]表示n的中的种类数。 规定ans[0] = ans[1] = 1;

如果给出的数是n那么从1開始, 与1之间相连的数与1之间间隔的对数各自是0, 1, 。。n-1, 那么我们就能够将他们切割成两部分,对于每一部分我们分别将其的结果求出,之后再相乘就是间隔对数s(s是0, 。。

n-1)的总的种类数。

最后我们能够总结出ans[n] = ans[0]*ans[n-1]+ans[1]*ans[n-2]+...ans[n-1]*ans[0];即为卡特兰数。

如果给出的是4。那么一共同拥有8个数。依照顺时针排列,我们如果从1開始,那么1能够与2(之间相差0个数), 4(之间相差2个数), 6(之间相差4个数), 8(之间相差6个数)。假如我们知道相差n个数的的种类数,那么我们仅仅须要将他们相加。即为我们所要求的总种类数。

以下我就依照上面的样例即n=4分析一下。

相差为0的时候,我们仅仅须要考虑剩下的三对就可以。则相差为0的种类数就为ans[3]*ans[0],之间相差2的时候我们就吧原有的序列分成了两部分,第一部分仅仅有2个数。第二部分有4个数。那么相差为2的种类数就是ans[2]*ans[1];相差为4的事实上就是上面情况的第一部分和第二部分颠倒了,这样的情况下的种类数是ans[1]*ans[2],相差为6就是第一种情况的颠倒,所以种类数是ans[3]*ans[0];

代码:

#include <cstdio>
#include <cstring>
int ans[102][100];

void table(){
	ans[0][0] = ans[1][0] = 1;
	int i, j;
	for(i = 2; i < 102; i ++){
		int c = 0;
		for(j = 0; j < 100; j ++){
			ans[i][j] = ans[i-1][j]*(4*i-2)+c;
			c = ans[i][j]/10;
			ans[i][j] %= 10;
		}
		int z = 0;
		for(j = 99; j >= 0; j --){
			z= z*10+ans[i][j];
			ans[i][j] = z/(i+1);
			z %= (i+1);
		}
	}
}
int main(){
	table();
	int temp;
	while(scanf("%d", &temp), temp != -1){
		int i = 99;
		while(ans[temp][i] == 0) i --;
		while(i >= 0) printf("%d", ans[temp][i]), i--;
		printf("\n");
	}
	return 0;
}
题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=164
      http://poj.org/problem?id=2084
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值