题目链接
题解:
n个座位不同,m个人去坐(人是一样的),每个人之间至少相隔k个座位问方案数思路:
定好m个人 相邻人之间k个座位 剩下就剩n-(k+1)*m个座位
剩下座位去插m个不同的盒子==就等价n个相同的球放m个不同的盒子
然后组合数出来了
乘n的话是枚举座位,除m是去掉枚举第一个座位的时候,剩下人相邻的座位相对不变的情况
代码
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<cstdlib>
#include<vector>
const int maxn = 1000000+10;
using namespace std;
typedef long long LL;
using namespace std;
const LL mod = 1e9+7;
int f[maxn];
void init() {
f[0] = 1;
for (int i=1; i<=maxn-5; i++)
f[i] = 1LL*f[i-1]*i%mod;
}
int inv(int x) {
int ret = 1, y=mod-2;
while (y) {
if (y&1)
ret = 1LL*ret*x%mod;
x = 1LL*x*x%mod;
y >>= 1;
}
return ret;
}
int C(int n, int m) {
if (n < m)
return 0;
int ret = 1LL*f[n]*inv(f[m])%mod;
ret = 1LL*ret*inv(f[n-m])%mod;
return ret;
}
int lucas(int n, int m) {
if (m == 0)
return 1;
return 1LL*C(n%mod, m%mod)*lucas(n/mod, m/mod)%mod;
}
int main() {
int T;
init();
scanf("%d", &T);
while (T--) {
int n, m, k;
scanf("%d%d%d", &n, &m, &k);
if (m == 1) {
printf("%d\n", n);
continue;
}
if (n < m*(k+1)) {
printf("0\n");
continue;
}
LL res = lucas(n-m*k-1, m-1);
LL ans = (res%mod)*n%mod;
printf("%lld\n", (ans*inv(m))%mod);
}
return 0;
}