題目鏈接:https://vjudge.net/problem/HDU-2067
?
小兔的棋盤
Time Limit: 1000/1000 MS (Java/Others)????Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11800????Accepted Submission(s): 5952
?
?
題解:
1?卡特蘭數的初步學習,卡特蘭數應用 。
2.卡特蘭數計算公式:
?1) h(n) = h(0)*h(n-1) + h(1)*h(n-2) + ... + h(n-1)h(0) (n>=1) , 其中 h[0] = 1;
?2) h(n) = c(2n,n) - c(2n,n+1)(n=0,1,2,...) <==>?h(n) = C(2n,n)/(n+1)
?3) h(n) = h(n-1)*(4*n-2) / (i+1)? ……此條計算公式容易溢出
注意:卡特蘭數的計算很容易溢出。
?
代碼如下:


1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <cmath> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 using namespace std; 13 typedef long long LL; 14 const int INF = 2e9; 15 const LL LNF = 9e18; 16 const int MOD = 1e9+7; 17 const int MAXN = 35+10; 18 19 LL h[MAXN]; 20 21 void init() 22 { 23 memset(h, 0, sizeof(h)); 24 h[0] = 1; h[1] = 1; 25 for(int i = 2; i<MAXN; i++) 26 for(int j = 0; j<i; j++) 27 h[i] += 1LL*h[j]*h[i-j-1]; 28 } 29 30 int main() 31 { 32 init(); 33 int kase = 0, n; 34 while(scanf("%d", &n) && n!=-1) 35 printf("%d %d %lld\n", ++kase, n, 2LL*h[n]); 36 }
?
?
?
題目鏈接:?https://vjudge.net/problem/HDU-4165
?
Pills
Time Limit: 2000/1000 MS (Java/Others)????Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1626????Accepted Submission(s): 1139
?
On the first day, she removes a random pill, breaks it in two halves, takes one half and puts the other half back into the bottle.
On subsequent days, she removes a random piece (which can be either a whole pill or half a pill) from the bottle. If it is half a pill, she takes it. If it is a whole pill, she takes one half and puts the other half back into the bottle.
In how many ways can she empty the bottle? We represent the sequence of pills removed from the bottle in the course of 2N days as a string, where the i-th character is W if a whole pill was chosen on the i-th day, and H if a half pill was chosen (0 <= i < 2N). How many different valid strings are there that empty the bottle?
?
?
題解:
有n片藥,每天吃半片。當天要么在藥罐中抽到把一片完整的藥片,然后分成兩半,吃一半,最后把另一半放回藥罐中;要么抽到半片藥片直接吃。問:有多少種情況? 單純的卡特蘭數。
?
代碼如下:


1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <cmath> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 using namespace std; 13 typedef long long LL; 14 const int INF = 2e9; 15 const LL LNF = 9e18; 16 const int MOD = 1e9+7; 17 const int MAXN = 30+10; 18 19 LL h[MAXN]; 20 21 void init() 22 { 23 memset(h, 0, sizeof(h)); 24 h[0] = 1; 25 for(int i = 1; i<MAXN; i++) 26 for(int j = 0; j<i; j++) 27 h[i] += 1LL*h[j]*h[i-j-1]; 28 } 29 30 int main() 31 { 32 init(); 33 int n; 34 while(scanf("%d", &n) && n) 35 printf("%lld\n", h[n]); 36 }
?
?
?
題目鏈接:https://vjudge.net/problem/HDU-1134
Game of Connections
Time Limit: 2000/1000 MS (Java/Others)????Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5112????Accepted Submission(s): 2934
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?
?
?
?
?
題意:
1~2*n 順時針排列成一圈, 用n條線段連接n對數,要求線段不能有交叉,問:有多少種連接情況?
?
題解:
可以將此題聯想到出棧問題,這樣就轉化成卡特蘭數了。
?
遞推式一:


1 import java.util.Scanner; 2 import java.math.BigInteger; 3 4 public class Main { 5 6 public static void main(String[] args){ 7 8 BigInteger[] a = new BigInteger[105]; 9 10 a[0] = BigInteger.ONE; 11 for(int i=1; i<=100; i++) { 12 a[i] = BigInteger.valueOf(0); 13 for(int j=0;j<i;j++){ 14 a[i] = a[i].add(a[j].multiply(a[i-j-1])); 15 } 16 } 17 18 Scanner input = new Scanner(System.in); 19 while(input.hasNext()){ 20 int n=input.nextInt(); 21 if(n==-1) break; 22 System.out.println(a[n]); 23 } 24 } 25 }
?
遞推式二:


1 import java.util.Scanner; 2 import java.math.BigInteger; 3 4 public class Main { 5 6 public static void main(String[] args){ 7 8 BigInteger[] a = new BigInteger[105]; 9 10 a[0] = BigInteger.ONE; 11 for(int i=1; i<=100; i++) { 12 a[i] = a[i-1].multiply(BigInteger.valueOf(4*i-2)).divide(BigInteger.valueOf(i+1)); 13 } 14 15 Scanner input = new Scanner(System.in); 16 while(input.hasNext()){ 17 int n=input.nextInt(); 18 if(n==-1) break; 19 System.out.println(a[n]); 20 } 21 } 22 }
?