zoukankan      html  css  js  c++  java
  • ZOJ 2688 The Review Plan II

    https://zoj.pintia.cn/problem-sets/91827364500/problems/91827369470

    题意:

    n天n个计划,一天完成一个计划,第i个计划不能在第i天和第i+1天完成,第n个计划不能在第n天和第1天完成,求安排计划的方案数。

    有禁区的排列问题

    在n*n有禁区棋盘上放n个棋子,每行每列只能放1个,第i行的禁区为第i和i+1列,第n行禁区为第n和1列

    根据容斥原理,得 方案数=n! - r1(n-1)! + r2(n-2)! - …… ± rn

    其中ri表示把i个旗子放在禁区的方案数

    禁区可以看做是由2n个数组成的圆环

    求ri相当于求在圆环上选i个不相邻的数的方案数

    根据定理从{1,2,3……n}中选r个不相邻的数的组合,其组合数为C(n-k+1,k)

    可以推出从圆环上选i个不相邻的数的组合,方案数为 C(2n-k+1,k)-C(2n-k-1,k-2)

    #include<cstdio>
    
    using namespace std;
    
    const int mod=1e9+7;
    #define N 200001
    
    int inv[N],fac[N];
    
    int pow(int a,int b)
    {
        int p=1;
        for(;b;b>>=1,a=1LL*a*a%mod)
            if(b&1) p=1LL*p*a%mod;
        return p;
    }
    
    int C(int n,int k)
    {
         return 1ll*fac[n]*inv[k]%mod*inv[n-k]%mod;
    }
    
    int main()
    {
         fac[0]=fac[1]=1;
         for(int i=2;i<N;++i) fac[i]=1ll*fac[i-1]*i%mod;
         inv[0]=inv[1]=1;
         for(int i=2;i<N;++i) inv[i]=pow(fac[i],mod-2); 
         int n,ans;
         long long t;
         while(scanf("%d",&n)!=EOF)
         {
             if(n==1) 
             {
                  printf("0
    ");
                  continue;
             }
             ans=fac[n]-1LL*n*2*fac[n-1]%mod;
              t=1;
             for(int i=2;i<=n;++i,t=-t)
              {
                  ans+=t*fac[n-i]*(C(2*n-i+1,i)-C(2*n-i-1,i-2))%mod;
                  ans%=mod;
             }
              if(ans<0) ans+=mod;
             printf("%d
    ",ans);    
        }
        return 0;
    }
             
  • 相关阅读:
    PM对功能模块的说明
    第四个迭代目标
    第三个迭代任务
    第三个迭代目标
    记账本状态图
    记账本数据流图
    记账本ER图
    记账本用例图
    第二个迭代目标
    记账本时序图
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12244674.html
Copyright © 2011-2022 走看看