HDU5894-hannnnah_j’s Biological Test【组合数学】

原题链接
hannnnah_j’s Biological Test

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 114 Accepted Submission(s): 23

Problem Description
hannnnah_j is a teacher in WL High school who teaches biology.

One day, she wants to test m students, thus she arranges n different seats around a round table.

In order to prevent cheating, she thinks that there should be at least k empty seats between every two students.

hannnnah_j is poor at math, and she wants to know the sum of the solutions.So she turns to you for help.Can you help her? The answer maybe large, and you need to mod 1e9+7.

Input
First line is an integer T(T≤1000).
The next T lines were given n, m, k, respectively.
0 < m < n < 1e6, 0 < k < 1000

Output
For each test case the output is only one integer number ans in a line.

Sample Input
2
4 2 6
5 2 1

Sample Output
0
5

Source
2016 ACM/ICPC Asia Regional Shenyang Online

Recommend
wange2014 | We have carefully selected several similar problems for you: 5901 5900 5899 5898 5897

这个题的题意很简单。就是一个环上有n个空位,然后安排m个人在这个环上就坐,每个人中间必须隔k个,问一共有多少种安排的方法。需要知道的是位置是不同的,但是人可以认为是一样的,因为只需要每个人中间有那么多的空格就可以了。如果把一个人A固定下来,那么入如下图的数据
这里写图片描述
这是必须要放下的座位就是这个样子,剩下的n-mk-1个位置随便你怎么摆都是没有问题且是唯一的。所以只需要从n-mk-1中挑选m-1个位置放人就可以了。A的位置有n种可能,然后A是m个人中的某一个,但是这里算的时候是按照所有人都是A的情况来取的,所以最后的结果表达出来就是
这里写图片描述
下面附代码

//http://acm.split.hdu.edu.cn/showproblem.php?pid=5894
#include <algorithm>
#include <iostream>
#include <utility>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
using namespace std;

typedef long long ll;
const int MOD = int(1e9) + 7;
//int MOD = 99990001;
const int INF = 0x3f3f3f3f;
const ll INFF = (~(0ULL)>>1);
const double EPS = 1e-9;
const double OO = 1e20;
const double PI = acos(-1.0); //M_PI;
const int fx[] = {-1, 1, 0, 0};
const int fy[] = {0, 0, -1, 1};
const int maxn=1000000 + 5;
//a对mod的逆元,mod为质数
ll niyuan(ll n,ll p)
{
    ll m=p-2,ans=1;
    while(m)
    {
        if(m&1) ans=ans*n%p;
        m>>=1;
        n=n*n%p;
    }
    return ans;
}
ll C(int m,int n){//从n个数中挑出m个数的种数
        ll res=1;
        if(m==0 || m==n) return 1;
        if(m==1) return n;
        for(ll i=0;i<m;i++)
                res=(res*(n-i))%MOD;
        for(ll i=1;i<=m;i++)
                res=(res*niyuan(i,MOD))%MOD;
        //cout << "C:(" <<m<<"," <<n <<")="<<res <<endl;
        return res;
}
int main(){
        ll T,n,m,k;cin >> T;
        while(T--){
                cin >> n >> m >> k;
                if(m==1){
                        printf("%d\n",n);
                        continue;
                }
                if(n-m-m*k<0){
                        printf("0\n");
                        continue;
                }
                ll res=(n*C(m-1,n-m*k-1))%MOD;
                res=(res*niyuan(m,MOD))%MOD;
                cout << res << endl;
        }
        return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

门豪杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值