【NOIP2013模拟联考6】选课

题目

你真的认为选课是那么容易的事吗?HYSBZ的ZY同志告诉你,原来选课也会让人产生一种想要回到火星的感觉。假设你的一周有n天,那么ZY编写的选课系统就会给你n堂课。但是该系统不允许在星期i和星期i+1的时候选第i堂课,也不允许你在星期n和星期一的时候选第n堂课。然后连你自己也搞不清哪种选课方案合法,哪种选课不合法了。你只想知道,你到底有多少种合法的选课方案。

分析

声明一下,参考了题解。
我们定义\(W_k\)表示至少有k节课选错的方案数,
求出这个,用容斥原理就很容易求出正确选课方案数量。
那怎么求\(W_k\)呢?
现在总共 n 堂课分别记为 1,2,...n,它们可放的天数可以表示为(1,2)(2,3)(3,4)...(n,1)现在我们把括号去掉即得到一个数列 1,2,2,3,3,4,....n,1,现在我们从里面取出 K 个数,分别表示 k 堂课所在的天数,现在只要求出满足这个条件的取法数就可以了。
但是,我们不能再同一天选两节课,那么第\(i*2-1和第i*2\)个数是不可以同时取的,
接着,我们不能重复取一节课,那么第\(i*2和第i*2+1\)个数是不可以同时取的(当然,最后一个“1”和最前面的“1”也是不可以同时取的)。
也就是说,对于一个环,求从其中选取k个不相邻顶点得方案数:\(C_{2n-k-1}^{k-1}*\dfrac{2n}{k}\)
证明:对于任意一个顶点A,先取A,然后再从不和A相邻的n-3个其他顶点中取k-1个不相邻顶点,显然可得到符合定理要求的组合,这个组合的个数为C((n-3)-(k-1)+1,k-1)=C(n-k-1,k-1)。一共有n个顶点,而且在每个组合中有k个元素,即可完成证明。
然后其余的随便选,
所以\(W_{k}=C_{2n-k-1}^{k-1}*\dfrac{2n}{k}*(n-k)!\)
THEN?容斥。
据说有种更强大的方法:这道提示有递推式滴!!!
这里写图片描述
但方法实在是太神奇了,根本就搞不懂。+_+

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const long long maxlongint=2147483647;
const long long mo=1000000007;
using namespace std;
long long jc[210000],ans,n,ny[210000],nn[210000];
long long mi(long long x,long long y)
{
    long long sum=1;
    while(y)
    {
        if(y&1) sum=sum*x%mo;
        x=x*x%mo;
        y/=2;
    }
    return sum;
}
long long C(long long m,long long n)
{
    return jc[m]*nn[m-n]%mo*nn[n]%mo;
}
long long W(long long k)
{
    return n*2*ny[n*2-k]%mo*C(n*2-k,k)%mo*jc[n-k]%mo;
}
int main()
{
    for(long long i=0;i<=200005;i++)
        ny[i]=mi(i,mo-2);
    jc[0]=1;
    nn[0]=1;
    for(long long i=1;i<=200005;i++)
    {
        jc[i]=jc[i-1]*i%mo;
        nn[i]=mi(jc[i],mo-2);
    }
    while(scanf("%lld",&n)!=EOF)
    {
        if(n==1)
        {
            printf("0\n");
            continue;
        }
        ans=jc[n];
        for(long long i=1;i<=n;i++)
        {
            if(i%2)
                ans=(ans-W(i)+mo)%mo;
                    else 
                        ans=(ans+W(i))%mo;
        }
        printf("%lld\n",ans);
    }
}

猜你喜欢

转载自www.cnblogs.com/chen1352/p/9029704.html