HDU 5894 hannnnah_j’s Biological Test (组合数学 + 快速幂 + 乘法逆元)

78 篇文章 0 订阅
5 篇文章 0 订阅

大体题意:

给你n 个座位,和m 个人, 安排在一个圆桌子上,要求任意两个人之间的座位至少为k 个,求方案数,答案对1e9取模?

思路:

我们先给m 个人放好,然后在每个人后在添加k 个座位,先保证至少k 个座位,然后会剩下 n - m - m*k个座位,在把剩下的座位插到已经存在的座位里。

那么这个问题就可以转换为:

你有n-m-m*k个球,要求放在m个不同的箱子里,有几种放法?

如果有n 个球,放在m 个不同箱子里。

可以这么考虑,在n  个球后 插入m-1个球,然后任意挑选m-1个球作为隔板,那么答案就是C(n+m-1,m-1)

那么这个题的答案就是 C(n-m-m*k+m-1,m-1) *n/m

之所以乘以n 是因为第一个学生有n 种选择,任意挑选一个座位,但是这样的话难免重复,因为1 3 5 和 3 5 1 和 5 1 3 是一样的,在除以m   就是学生重复的!

然后就是组合数递推取模了,  会有除法,直接快速幂逆元即可!

注意:

只有一个学生,这个公式是不成立的,需要单独判断!

m = 1, ans=n;

在一点是 递推组合数时,不能直接从1递推到n,这样会超时,应该从1 算到  m-1。

详细见代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int maxn = 1000000 + 10;
ll c[maxn];
ll my_pow(ll a,ll n){
    ll ans = 1;
    while(n){
        if (n & 1)
            ans = (ans % mod * a % mod) % mod;
        n/=2;
        a = (a%mod*a%mod)%mod;
    }
    return ans;
 }

ll C(ll n,ll m){
	c[0] = 1;
	for (int i = 1; i <= m; ++i)c[i] = (((c[i-1]%mod * (n-i+1)%(mod)) ) * my_pow(i,mod-2)) % mod;
}
ll n, m, k;
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		scanf("%I64d%I64d%I64d",&n, &m, &k);
		if (m == 1){
			printf("%d\n",n);
			continue;
		}
		if (n < m + m*k){
			printf("0\n");
			continue;
		}
		C(n-m*k-1,m-1);
		ll ans = (((n%(mod) * c[m-1] % (mod))%(mod))*my_pow(m,mod-2)) % mod;
		printf("%I64d\n",ans);	
	}
	return 0;
}

Time Limit: 1000MS Memory Limit: 131072KB 64bit IO Format: %I64d & %I64u

 Status

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

Problem descriptions:
System Crawler 2016-09-18
Initialization.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值