题意: 一场舞会,需要从n个人里挑出m个人上台表演,问共有多少种情况。
思路:即求c(m,n) 。 在计算过程中有点技巧,注释在代码里
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[50];
int main(void)
{
int t;
cin >> t;
while(t--)
{
int n,m;
cin >> n >>m;
if(n<m ) cout << "0"<<endl;
else
{
a[0]=1; // 解决了m=0的问题,同时为下面a[1]计算做铺垫
for(int i=1;i<=m;i++)
a[i]=a[i-1]*(n-i+1)/i;//先乘再除
cout << a[m]<< endl;
}
}
}
2018.10.13
用逆元求组合数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200000 + 5;
const int MOD = (int)1e9 + 7;
int F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘
void init(){
inv[1] = 1;
for(int i = 2; i < N; i ++){
inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
}
F[0] = Finv[0] = 1;
for(int i = 1; i < N; i ++){
F[i] = F[i-1] * 1ll * i % MOD;
Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD;
}
}
int comb(int n, int m){//comb(n, m)就是C(n, m)
if(m < 0 || m > n) return 0;
return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD;
}
int main()
{
init();
int t,n,m;
cin >>t ;
while(t--){
cin >>n >>m;
ll ans=comb(n,m);
cout << ans << endl;
}
}