hint:这个题目要用大数。
题意:给出连续的2*n个点,序号分别为1,2,3...2n,放在一个圆周上。之后分成n组,每组两个点相连。
要求所有直线互不相交的连线方法种数。
1.很容易想到递推。
ans[x]=ans[x].add(ans[le].multiply(ans[ri]) );
2.这个题就是卡特兰数
直接利用公式
令h(0)=1,h(1)=1,catalan数满足递推式[1] :
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,...)
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 8161 | Accepted: 4071 |
Description
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
You may assume that 1 <= n <= 100.
Output
Sample Input
2 3 -1
Sample Output
2 5
Source
import java.math.BigInteger;
import java.util.Scanner;
/*
递推求解
*/
public class Main {
static int n;
final static int maxn=100;
static BigInteger [] ans=new BigInteger[maxn+10];
static void cal(int x)
{
ans[x]=BigInteger.ZERO;
for(int le=0;le+1<=x;le++)
{
int ri=x-le-1;
ans[x]=ans[x].add(ans[le].multiply(ans[ri]) );
}
}
static void pre()
{
ans[0]=BigInteger.ONE;
ans[1]=BigInteger.ONE;
for(int x=2;x<=100;x++)
{
cal(x);
}
}
public static void main(String args[])
{
pre();
Scanner sc=new Scanner(System.in);
while(sc.hasNextInt())
{
n=sc.nextInt();
if(n==-1)
{
break;
}
System.out.println(ans[n]);
}
}
}
import java.math.BigInteger;
import java.util.Scanner;
/*
卡特兰数
令h(0)=1,h(1)=1,catalan数满足递推式[1] :
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,...)
*/
public class Main {
static int n;
static final int maxn=200;
static BigInteger [][] C=new BigInteger[maxn+10][maxn+10];
static void pre()
{
C[1][0]=C[1][1]=BigInteger.ONE;
for(int i=2;i<=maxn;i++)
{
C[i][0]=C[i][i]=BigInteger.ONE;
for(int j=1;j<i;j++)
{
C[i][j]=C[i-1][j-1].add(C[i-1][j]);
}
}
}
public static void main(String args[])
{
pre();
Scanner sc=new Scanner(System.in);
while(sc.hasNextInt())
{
n=sc.nextInt();
if(n==-1)
{
break;
}
BigInteger ret=C[2*n][n].subtract(C[2*n][n-1]);
System.out.println(ret);
}
}
}
卡特兰数前几项:
1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, ...