HDU1134——Game of Connections

3 篇文章 0 订阅
3 篇文章 0 订阅

题目描述:

Problem Description
This is a small but ancient game. You are supposed to write down the numbers 1, 2, 3, ... , 2n - 1, 2n consecutively in clockwise order on the ground to form a circle, and then, to draw some straight line segments to connect them into number pairs. Every number must be connected to exactly one another. And, no two segments are allowed to intersect.

It's still a simple game, isn't it? But after you've written down the 2n numbers, can you tell me in how many different ways can you connect the numbers into pairs? Life is harder, right?
 
Input
Each line of the input file will be a single positive number n, except the last line, which is a number -1. You may assume that 1 <= n <= 100.
Output
For each n, print in a single line the number of ways to connect the 2n numbers into pairs.
Sample Input
  
  
2 3 -1
 
Sample Output
  
  
2 5

 

思路:

该题是一个卡特兰数列,即1,1,2,5,14,42.....,卡特兰数Cn=(2n)!/((n+1)!*n!);卡特兰数递推式:C(n)=((4n-2)/(n+1))*C(n-1);该题还有一个重要的问题——高精度的大数。可以用大数的乘法和除法处理数据

 

代码:

#include<iostream>
using namespace std;
#define SIZE 100
int n;
int a[101][SIZE]= {0}; //数组用来存放结果 并且初始化
int main()
{
     int i,j,r=0;
     int temp = 0,len = 1;  //len 表示当前最长的有效位数,初始化为1
     a[1][0] = 1;
     for(i = 2; i <= 100; i++)//从第二项 到 第一百项, 用公式计算
     {
         for(j = 0; j < len; j ++)// 依次作乘法
             a[i][j] = a[i-1][j]*(4*i-2);//从低位到高位
         for(j = 0; j < len; j++)//对乘出来的结果 进行处理
         {
             temp = a[i][j] + r;
             a[i][j] = temp%10;
             r = temp/10;
         }
         while(r)              //对高位进行处理
         {
             a[i][len] = r%10;
             r /= 10;
             len++;
         }
         for(j = len-1,r = 0; j >= 0;j--)//模拟除法 从高位到低位
         {
             temp = r*10+a[i][j];
             a[i][j] = temp/(i+1);
             r = temp%(i+1);
         }
         while(!a[i][len-1])     //处理高位的 0 
             len--;
     }
     while(scanf("%d",&n)!=EOF)//
     {
         if(n<0) break;
         for(i = SIZE-1; !a[n][i];i--);
         for(i;i>=0;i--){printf("%d",a[n][i]);}
         printf("\n");
     }
     return 0;
}

 

关于卡特兰数其他的一些应用:

①可以表示dyck word的个数,Dyck word是一个有n个x和n个y组成的字串,且所有的前缀字串皆满足x的个数大于等于y的个数。

②可以表示有n+1个叶子的二叉树的个数

③可以表示所有不同构的含n个分支结点的满二叉树的个数

④可以表示n*n格点中不越对角线的单调路径的个数

⑤可以表示通过连接顶点而将n+2的凸多边形分成三角形的方法数

⑥可以表示对{1,..........,n}依序进出栈的置换个数(对于什么是置换不是很明白啊。。。。。。)

⑦可以表示{1,..........,n}的不交叉划分的个数,也表示{1,..........,2n}的不交叉划分的个数,即该题的情况

⑧可以表示用n个长方形填充一个高度为n的阶梯状图形的方法

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值