码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5894 hannnnah_j’s Biological Test (组合数学) -2016 ICPC沈阳赛区网络赛

时间:2016-09-19 19:38:47      阅读:246      评论:0      收藏:0      [点我收藏+]

标签:

题目链接

题意:一个大小为 nn 的环,选 mm 个位置涂黑,要求相邻两个黑点之间至少间隔 kk 个白点,问方案数。

题解:考虑从 0 开始的标号最小的涂黑的位置,有两种情况:

如果该位置 \geq kk,相当于在一排(不是环) n - knk 个椅子里面放 mm 个人;
如果该位置 < k<k, 相当于在一排 n - 2k - 1n2k1 个椅子里面放 (m - 1)(m1) 个人。这种情况有 k 种。

最后考虑在一排 nn 个椅子里面放 mm 个人的方案数,相当于要找 (m + 1)(m+1) 个变量满足 x_1 \geq 0, x_{2, 3, \ldots, m} \geq k + 1, x_{m + 1} \geq 1x?1??0,x?2,3,,m??k+1,x?m+1??1 同时 x_1 + x_2 + \cdots + x_{m + 1} = nx?1??+x?2??+?+x?m+1??=n 的方案数。这个方案数就是 \binom{n - (m - 1)k}{m}(?m?n(m1)k??).

至于为什么是上述式子,其中 x_1x?1?? 表示的是 11 的下标,x_{2, 3, \ldots, m}x?2,3,,m?? 表示的是每个人离前一个人的距离,最后的 x_{m + 1}x?m+1?? 是松弛变量。可以加加减减让大家的限制都变成 \geq 11,就是熟悉的模型啦。

#include <map>
#include <queue>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
using namespace std;
long long a[1000005];
const long long mod=1000000007;
long long quick(long long a,long long b)
{
    long long ans=1;
    while(b)
    {
        if(b&1) {
            ans=ans*a%mod;
            b--;
        }
        b>>=1;
        a=a*a%mod;
    }
    return ans;
}
int main()
{
    int T;
    long long i,n,m,k;
    a[1]=1;
    for(i=2; i<=1000000; i++)
        a[i]=(a[i-1]*i)%mod;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld%lld",&n,&m,&k);
        if(m==1)
            printf("%lld\n",n);
        else if(m+m*k>n)
            printf("0\n");
        else if(m+m*k==n)
            printf("%lld\n",k+1);
        else {
            long long y=m-1;
            long long x=n-m*k-1;
            long long ans=a[x]*quick(a[x-y],mod-2)%mod*quick(a[y],mod-2)%mod;
            printf("%lld\n",n*ans%mod*quick(m,mod-2)%mod);
        }
    }
    return 0;
}

 

HDU 5894 hannnnah_j’s Biological Test (组合数学) -2016 ICPC沈阳赛区网络赛

标签:

原文地址:http://www.cnblogs.com/Ritchie/p/5886240.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!