可参考:https://blog.csdn.net/wentong_Xu/article/details/81428630
出栈序列方案数:f(n)=h(n)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import java.util.Scanner; 2 import java.io.BufferedInputStream; 3 import java.math.BigInteger; 4 public class Main { 5 public static void main(String[] args) { 6 // TODO 自动生成的方法存根 7 BigInteger[] h=new BigInteger[101]; 8 h[0]=new BigInteger("1"); 9 h[1]=new BigInteger("1"); 10 int MAXN=100; 11 for(int i=2;i<=MAXN;++i) 12 { 13 h[i]=h[i-1].multiply(BigInteger.valueOf(4*i-2)); 14 h[i]=h[i].divide(BigInteger.valueOf(i+1)); 15 } 16 Scanner cin=new Scanner(new BufferedInputStream(System.in)); 17 while(cin.hasNext()) 18 { 19 int n=cin.nextInt(); 20 System.out.println(h[n]); 21 } 22 cin.close(); 23 } 24 25 }
n个红算筹和n个黑算筹的摆放,前i个中红算筹的个数大于黑算筹的个数,f(2n)=h(n),模100
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int MAXN=100+5; 5 const int MOD=100; 6 ll h[MAXN]; 7 int main() 8 { 9 h[0]=1,h[1]=1; 10 /*for(int i=2;i<=MAXN;++i) 11 h[i]=h[i-1]*(4*i-2)%MOD/(i+1);*/ 12 //上述递推式在这里行不通 13 for(int i=2;i<=MAXN;++i) 14 { 15 for(int j=0;j<i;++j) 16 h[i]+=h[j]*h[i-j-1]%MOD; 17 h[i]%=MOD; 18 } 19 int n;cin>>n; 20 cout<<h[n]<<endl; 21 }
动态规划做法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int MAXN=100+5; 5 const int MOD=100; 6 ll dp[MAXN<<1][MAXN];//dp[i][j]表示前i个中有j个是红色 7 int main() 8 { 9 int n;cin>>n; 10 n*=2; 11 dp[1][1]=1;//第一个一定是红色 12 for(int i=2;i<=n;++i) 13 { 14 for(int j=(i+1)>>1;j<=i;++j) 15 dp[i][j]=(dp[i-1][j]%MOD+dp[i-1][j-1]%MOD)%MOD;//第i个放黑色或红色 16 } 17 cout<<dp[n][n>>1]; 18 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int MAXN=100+5; 5 const int MOD=100; 6 ll dp[MAXN<<1][MAXN<<1];//dp[i][j]表示前i个中红色比黑色多j个 7 int main() 8 { 9 int n;cin>>n; 10 n*=2; 11 dp[1][1]=1;//第一个一定是红色 12 for(int i=2;i<=n;++i) 13 { 14 for(int j=0;j<=i;++j) 15 { 16 dp[i][j]+=dp[i-1][j-1]%MOD;//第i个放红色 17 dp[i][j]+=dp[i-1][j+1]%MOD;//第i个放黑色 18 dp[i][j]%=MOD; 19 } 20 } 21 cout<<dp[n][0]; 22 }
圆上2n个点,用n条线段将这些点连起来,不能有线段相交。f(2n)=h(n)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int MAXN=3e3; 5 const int MOD=1e8+7; 6 ll h[MAXN]={1,1}; 7 int main() 8 { 9 int n;cin>>n; 10 for(int i=2;i<=n;++i) 11 for(int j=0;j<i;++j) 12 h[i]=(h[j]*h[i-j-1]%MOD+h[i])%MOD; 13 cout<<h[n]<<endl; 14 }
棋盘上从(0,0)到(n,n)且不穿越对角线的路径数。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import java.util.Scanner; 2 import java.io.BufferedInputStream; 3 import java.math.BigInteger; 4 public class Main { 5 public static void main(String[] args) { 6 // TODO 自动生成的方法存根 7 BigInteger[] h=new BigInteger[36]; 8 h[0]=new BigInteger("1"); 9 h[1]=new BigInteger("1"); 10 int MAXN=35; 11 for(int i=2;i<=MAXN;++i) 12 { 13 h[i]=h[i-1].multiply(BigInteger.valueOf(4*i-2)); 14 h[i]=h[i].divide(BigInteger.valueOf(i+1)); 15 } 16 Scanner cin=new Scanner(new BufferedInputStream(System.in)); 17 int n=cin.nextInt(); 18 int count=0; 19 while(n!=-1) 20 { 21 22 System.out.print(++count+" "+n+" "); 23 System.out.println(h[n].multiply(new BigInteger("2"))); 24 n=cin.nextInt(); 25 } 26 cin.close(); 27 } 28 29 }
动态规划做法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import java.math.BigInteger; 2 import java.util.Scanner; 3 import java.io.BufferedInputStream; 4 public class Main { 5 static final int MAXN=40; 6 static BigInteger dp[][] = new BigInteger[MAXN][MAXN]; //dp[i][j]表示(0,0)到(i,j)的方案数 7 public static void main(String[] args) 8 { 9 Scanner cin=new Scanner(new BufferedInputStream(System.in)); 10 for(int i=0;i<MAXN;++i) 11 for(int j=0;j<MAXN;++j) 12 dp[i][j]=BigInteger.ZERO; 13 for(int i=0;i<MAXN;++i) dp[i][0]=BigInteger.ONE; 14 for(int i=1;i<MAXN;++i)//计算右下角 15 { 16 for(int j=1;j<=i;++j)//不穿越对角线 17 { 18 if(j==i) dp[i][j]=dp[i][j-1]; 19 else dp[i][j]=dp[i-1][j].add(dp[i][j-1]); 20 } 21 } 22 int n=cin.nextInt(); 23 int count=0; 24 while(n!=-1) 25 { 26 System.out.print(++count+" "+n+" "); 27 System.out.println(dp[n][n].multiply(new BigInteger("2"))); 28 n=cin.nextInt(); 29 } 30 cin.close(); 31 } 32 }
m个100,n个50,扩展的卡特兰
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import java.util.Scanner; 2 import java.math.BigInteger; 3 import java.io.BufferedInputStream; 4 5 public class Main { 6 static final int MAXN=200+5; 7 static BigInteger[] fac = new BigInteger[MAXN]; 8 public static void main(String[] args) { 9 Scanner cin=new Scanner(new BufferedInputStream(System.in)); 10 fac[0]=BigInteger.ONE; 11 for(int i=1;i<MAXN;++i) fac[i]=fac[i-1].multiply(BigInteger.valueOf(i)); 12 int m=cin.nextInt(); 13 int n=cin.nextInt(); 14 int count=1; 15 while(m!=0||n!=0) 16 { 17 BigInteger ans=BigInteger.ONE; 18 BigInteger fz=fac[m+n].multiply(BigInteger.valueOf(m+1-n)); 19 BigInteger fm=BigInteger.valueOf(m+1); 20 if(m<n) ans=BigInteger.ZERO; 21 else ans=fz.divide(fm); 22 System.out.println("Test #"+count+":"); 23 System.out.println(ans); 24 m=cin.nextInt(); 25 n=cin.nextInt(); 26 count++; 27 } 28 cin.close(); 29 } 30 31 }
2n个高矮不同的人,排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种
用Java大数做后面5组数据MLE了,可能大数太大了,又要用数论,告辞!