hdu 5894 组合Lucas

题目链接

题解:

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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值