Problem Description
开学了,杭电又迎来了好多新生。ACMer想为新生准备一个节目。来报名要表演节目的人很多,多达N个,但是只需要从这N个人中选M个就够了,一共有多少种选择方法?
Input
数据的第一行包括一个正整数T,接下来有T组数据,每组数据占一行。
每组数据包含两个整数N(来报名的人数,1<=N<=30),M(节目需要的人数0<=M<=30)
Output
每组数据输出一个整数,每个输出占一行
Sample Input
5
3 2
5 3
4 4
3 6
8 0
Sample Output
3
10
1
0
1
刚开始的思路
二项式系数C(n, k)满足下面的要求:
C(n, 0) = C(n, n) = 1 for all n > 0;
C(n, k) = C(n − 1, k − 1) + C(n − 1, k) for all 0 < k < n.
题目要求根据给定的n和k(0 ≤ k ≤ n < 231, n > 0)计算C(n,k),典型的递归问题。
但是如果采用递归,当n的值比较大的时候,会堆栈益处。而上面的表达式应该有相应的公式。如果采用公式计算就会变的简单了。
但是总是WA,最后发现是超出范围!!!
1 #include <stdio.h> 2 #include <iostream> 3 using namespace std; 4 int zuhe(int n,int k) 5 { 6 int *result = new int[n]; 7 for(int i=1;i<=n;i++) 8 { 9 result[i] = 1; 10 for(int j=i-1;j>=1;j--) 11 { 12 result[j] = result[j-1]+result[j]; 13 } 14 result[0] = 1; 15 } 16 return result[k]; 17 } 18 int main() 19 { 20 int t; 21 scanf("%d",&t); 22 while(t--) 23 { 24 int a,b; 25 scanf("%d%d",&a,&b); 26 if(b>a) 27 { 28 printf("0\n"); 29 continue; 30 } 31 printf("%d\n",zuhe(a,b)); 32 } 33 return 0; 34 }
可以这样:
1 #include<iostream> 2 using namespace std; 3 int c[31][31]; 4 int main() 5 { 6 int i,j; 7 for(i=1;i<31;i++) 8 {c[i][0]=1;c[i][1]=i;} 9 for(i=2;i<31;i++) 10 for(j=2;j<=i;j++) 11 c[i][j]=c[i-1][j]+c[i-1][j-1]; 12 int t,n,m; 13 while(scanf("%d",&t)!=EOF) 14 { 15 while(t--) 16 { 17 scanf("%d%d",&n,&m); 18 printf("%d\n",c[n][m]); 19 } 20 } 21 return 0; 22 }
之后通过了解:
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int main(void) 5 { 6 int m,n,t; 7 long long sum; 8 cin>>t; 9 while(t--) 10 { 11 cin>>n>>m; 12 sum=1; 13 for(int i=1;i<=m;i++) 14 { 15 sum*=n--; 16 sum/=i; 17 } 18 printf("%lld\n",sum); 19 } 20 return 0; 21 }
时间: 2025-01-14 13:56:57