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\n");
              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\n",ans);
    }
    return 0;
}
         

原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12244674.html

时间: 2024-10-04 03:53:54

ZOJ 2688 The Review Plan II的相关文章

zoj 3688 The Review Plan II 禁位排列 棋盘多项式 容斥

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4971 题意:共有N天和N个章节,每天完成一个章节,规定第i个章节不可以在第i天或者i+1天完成(第N个章节则是第N天和第1天不能),求分配能完成所有章节的方案数. 思路: 主要还是根据棋盘多项式的公式来求解: 但是这题和ZOJ3687不同,数据量N最大有100000,因此不能爆搜,需要推一下公式. 按照题意,先求禁位组成的棋盘的棋盘多项式,再用容斥.禁位组成的棋盘如

ZOJ 3687 The Review Plan I ( 禁位排列 + 容斥原理 )

ZOJ 3687 The Review Plan I ( 禁位排列 + 容斥原理 ) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; #define CLR( a, b ) memset( a, b, sizeof(a) ) #define MOD 55566677 #define MAXN 55 LL fac[MAX

ZOJ 3687 The Review Plan I

The Review Plan I Time Limit: 5000ms Memory Limit: 65536KB This problem will be judged on ZJU. Original ID: 368764-bit integer IO format: %lld      Java class name: Main Michael takes the Discrete Mathematics course in this semester. Now it's close t

zoj 3687 The Review Plan I 禁位排列 棋盘多项式

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3687 题意:有N天和N个章节,每天可以完成一个章节,有M个限制,表示第Di天不能完成章节Ci. 问共有多少种计划方案可以完成所有章节. 思路: 学习了一下棋盘多项式的知识 http://wenku.baidu.com/link?url=NXPYih0AzZJTi0Tqd4Qb91vq2Rz0f3YCm7IQpu0pcbPTlv75DeiVtTj81sDtqdnv

zoj 3557 How Many Sets II

How Many Sets II Time Limit: 2 Seconds      Memory Limit: 65536 KB Given a set S = {1, 2, ..., n}, number m and p, your job is to count how many set T satisfies the following condition: T is a subset of S |T| = m T does not contain continuous numbers

zoj——3557 How Many Sets II

How Many Sets II Time Limit: 2 Seconds      Memory Limit: 65536 KB Given a set S = {1, 2, ..., n}, number m and p, your job is to count how many set T satisfies the following condition: T is a subset of S |T| = m T does not contain continuous numbers

Zoj 3535 Gao the String II (AC自己主动机+dp)

题目大意: 用集合A中的串构造出一个串,使之让很多其它的setB中的串成为他的子串. 思路分析: 和 Codeforces 86C 几乎相同. 只是这里是要用A中的构造. 先用A 和 B的串构造一个自己主动机.然后对于A集合的尾结点给出一个最大后缀匹配,对于B集合的尾结点给一个权值. dp[i][j][k] 表示已经构造出来了一个长度为i的串,如今走到了自己主动机的j结点.i长度后面有k个字符是没有匹配到的. 继续在自己主动机上走进行状态转移. if(isword >= k +1 )dp [i+

ZOJ 3557 How Many Sets II lucas 定理

插空法 大组合数取余 #include <cstdio> #include <cstring> using namespace std; typedef long long LL; //求整数x和y,使得ax+by=d, 且|x|+|y|最小.其中d=gcd(a,b) void gcd(LL a, LL b, LL& d, LL& x, LL& y) { if(!b) { d = a; x = 1; y = 0; } else { gcd(b, a%b, d

Zoj 3535 Gao the String II (AC自动机+dp)

题目大意: 用集合A中的串构造出一个串,使之让更多的setB中的串成为他的子串. 思路分析: 和 Codeforces 86C 差不多. 不过这里是要用A中的构造. 先用A 和 B的串构造一个自动机.然后对于A集合的尾结点给出一个最大后缀匹配,对于B集合的尾结点给一个权值. dp[i][j][k] 表示已经构造出来了一个长度为i的串,现在走到了自动机的j结点,i长度后面有k个字符是没有匹配到的. 继续在自动机上走进行状态转移. if(isword >= k +1 )dp [i+1] [j->n