题意:
初始有n个房间每个房间有n个人,可以进行k次操作,每次操作选中任意一个人离开当前房间进入另一个房间。问经过k次操作后会有多少种情况。
思路:
枚举有多少个空房间。易知空房间最少有0个,最多有min(n-1,k)个。对于有i个空房间,那么剩下的 n-i 个房间必定有人,也就是将 n 个人放进这 n - i 个房间里有多少中情况(n-1个空隙放n-i-1个隔板),所以当前的情况数就是 C(n,i)*C(n-1,n-i-1)。枚举情况相加即可。
因为组合数过大,所以用小费马定理求组合数。
tip:
infact [ i ] = infact [ i - 1 ] *qmi ( i - 1, mod - 2, mod ) % mod
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10,mod=1e9+7;
int n,k;
int fact[N],infact[N];
int qmi(int a,int b,int p){
int res=1;
while(b){
if(b&1) res=(int)res*a%p;
a=(int)a*a%p;
b >>= 1;
}
return res;
}
void init(){
fact[0]=infact[0]=1;
for(int i=1;i<=N;i++){
fact[i]=(int)fact[i-1]*i%mod;
infact[i]=(int)infact[i-1]*qmi(i,mod-2,mod)%mod;
}
}
int C(int a,int b){
return (int)fact[a]*infact[a-b]%mod*infact[b]%mod;
}
signed main(){
init();
cin >> n >> k;
int res=0;
for(int i=0;i<=min(n-1,k);i++){
res=(int)(res+C(n,i)*C(n-1,n-i-1)%mod)%mod;
}
cout << res << endl;
return 0;
}