Codeforces 题目传送门 & 洛谷题目传送门

upd on 2021.10.20:修了个 typo(

这是一道 *2600 的 D2E,然鹅为啥我没想到呢?wtcl/dk

首先第一步我就没想到/kk,看到“恰好”二字我们可以想到一个东西叫做二项式反演(qwq 这个套路在刷多项式题时经常见到,可咋换个场景就想不到了呢?显然是我多项式白学了/doge)。我们设 \(f_k\) 表示恰好 \(k\) 个完美数的排列个数,\(g_k\) 表示钦定 \(k\) 个位置满足 \(|p_i-i|=1\),剩下随便乱填的方案数,那么显然对于某个有 \(x\) 个完美位置的排列,它被计入 \(g_y(y<x)\) 的次数为 \(\dbinom{x}{y}\)。

也就是说 \(g_k=\sum\limits_{i=k}^nf_i\dbinom{i}{k}\)​。反演一下可得 \(f_k=\sum\limits_{i=k}^n(-1)^{i-k}\dbinom{i}{k}g_i\)​。

故我们只需求出 \(g_i\) 就行了。

怎么求 \(g_i\) 呢?这时候就要用到 DP 了,我们设 \(dp_{i,j,x,y}\) 表示填好了前 \(i\) 个位置,钦定了 \(j\) 个位置满足 \(|p_i-i|=1\),\(x\) 表示 \(i\) 是否被选择,\(y\) 表示 \(i+1\) 是否被选择(这一步我又没想到,看来我 DP 也白学了/ww)。转移就分 \(i\) 不是被钦定为“完美位置”,\(p_i=i+1,p_i=i-1\) 三种情况转移即可,具体来说:

  • \(dp_{i,j,0,0}=dp_{i-1,j,0,0}+dp_{i-1,j,1,0}+dp_{i-1,j-1,0,0}\)(放 \(i-1\) 或者不被钦定为完美位置)
  • \(dp_{i,j,0,1}=dp_{i-1,j-1,0,0}+dp_{i-1,j-1,1,0}\)(\(y=1\),只能放 \(i+1\))
  • \(dp_{i,j,1,0}=dp_{i-1,j,0,1}+dp_{i-1,j,1,1}+dp_{i-1,j-1,0,1}\)(放 \(i-1\) 或者不被钦定为完美位置)
  • \(dp_{i,j,1,1}=dp_{i-1,j-1,0,1}+dp_{i-1,j-1,1,1}\)(\(y=1\),只能放 \(i+1\))

初始 \(dp_{1,0,0,0}=dp_{1,1,0,1}=1\)。

最后 \(g_k=(dp_{n,k,0,0}+dp_{n,k,1,0})·(n-k)!\)(\(n+1\) 不能被选择),时间复杂度 \(n^2\)。

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXN=1000;
const int MOD=1e9+7;
int n,m,dp[MAXN+5][MAXN+5][2][2];
int fac[MAXN+5],ifac[MAXN+5];
void add(int &x,int y){x+=y;if(x>=MOD) x-=MOD;}
int binom(int x,int y){return 1ll*fac[x]*ifac[y]%MOD*ifac[x-y]%MOD;}
int main(){
scanf("%d%d",&n,&m);dp[1][1][0][1]=dp[1][0][0][0]=1;
fac[0]=1;ifac[0]=ifac[1]=1;
for(int i=2;i<=n;i++) ifac[i]=1ll*ifac[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%MOD,ifac[i]=1ll*ifac[i-1]*ifac[i]%MOD;
for(int i=2;i<=n;i++) for(int j=0;j<=i;j++){
if(j){
add(dp[i][j][0][0],dp[i-1][j-1][0][0]);
add(dp[i][j][1][0],dp[i-1][j-1][0][1]);
add(dp[i][j][0][1],dp[i-1][j-1][0][0]);
add(dp[i][j][0][1],dp[i-1][j-1][1][0]);
add(dp[i][j][1][1],dp[i-1][j-1][0][1]);
add(dp[i][j][1][1],dp[i-1][j-1][1][1]);
}
add(dp[i][j][0][0],dp[i-1][j][0][0]);
add(dp[i][j][0][0],dp[i-1][j][1][0]);
add(dp[i][j][1][0],dp[i-1][j][0][1]);
add(dp[i][j][1][0],dp[i-1][j][1][1]);
} int ans=0;
for(int i=m;i<=n;i++){
int ways=1ll*(dp[n][i][0][0]+dp[n][i][1][0])*fac[n-i]%MOD;
if((i-m)&1) ans=(ans-1ll*ways*binom(i,m)%MOD+MOD)%MOD;
else ans=(ans+1ll*ways*binom(i,m))%MOD;
} printf("%d\n",ans);
return 0;
}

Codeforces 285E - Positions in Permutations(二项式反演+dp)的更多相关文章

  1. CodeForces - 285E: Positions in Permutations(DP+组合数+容斥)

    Permutation p is an ordered set of integers p1,  p2,  ...,  pn, consisting of n distinct positive in ...

  2. BZOJ3622 已经没有什么好害怕的了 二项式反演+DP

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3622 题解 首先显然如果 \(n - k\) 为奇数那么就是无解.否则的话,"糖果& ...

  3. CodeForces 340E Iahub and Permutations 错排dp

    Iahub and Permutations 题解: 令 cnt1 为可以没有限制位的填充数字个数. 令 cnt2 为有限制位的填充数字个数. 那么:对于cnt1来说, 他的值是cnt1! 然后我们对 ...

  4. Codeforces 285 E. Positions in Permutations

    \(>Codeforces \space 285 E. Positions in Permutations<\) 题目大意 : 定义一个长度为 \(n\) 的排列中第 \(i\) 个元素是 ...

  5. Codeforces 923E - Perpetual Subtraction(微积分+生成函数+推式子+二项式反演+NTT)

    Codeforces 题目传送门 & 洛谷题目传送门 神仙题 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 首先考虑最朴素的 \(dp\),设 \(dp_{z,i}\) 表示经 ...

  6. P4859 已经没有什么好害怕的了(dp+二项式反演)

    P4859 已经没有什么好害怕的了 啥是二项式反演(转) 如果你看不太懂二项式反演(比如我) 那么只需要记住:对于某两个$g(i),f(i)$ ---------------------------- ...

  7. 洛谷4859 BZOJ3622 已经没什么好害怕的了(DP,二项式反演)

    题目链接: 洛谷 BZOJ 题目大意:有两个长为 $n$ 的序列 $a,b$,问有多少种重排 $b$ 的方式,使得满足 $a_i>b_i$ 的 $i$ 的个数比满足 $a_i<b_i$ 的 ...

  8. BZOJ3622 已经没有什么好害怕的了 【dp + 二项式反演】

    题目链接 BZOJ3622 题解 既已开题 那就已经没有什么好害怕的了 由题目中奇怪的条件我们可以特判掉\(n - k\)为奇数时答案为\(0\) 否则我们要求的就是糖果大于药片恰好有\(\frac{ ...

  9. 51nod 1518 稳定多米诺覆盖(容斥+二项式反演+状压dp)

    [传送门[(http://www.51nod.com/Challenge/Problem.html#!#problemId=1518) 解题思路 直接算不好算,考虑容斥,但并不能把行和列一起加进去容斥 ...

随机推荐

  1. javascript的变量及数据类型

    1.变量的概念 变量是储存数据的内存空间 2.变量的命名规则 js变量的命名规则如下:以字母或者下划线开头可以包含字母.数字.下划线,不能包含特殊字符 3.变量的创建及初始化方法 方法一:先创建后使用 ...

  2. Idea Maven auto Import

  3. [no code][scrum meeting] Alpha 1

    项目 内容 会议时间 2020-04-06 会议主题 团队任务分析与拆解 会议时长 30min 参会人员 全体成员 $( "#cnblogs_post_body" ).catalo ...

  4. 【二食堂】Alpha - Scrum Meeting 10

    Scrum Meeting 10 例会时间:4.20 18:00~18:20 进度情况 组员 昨日进度 今日任务 李健 1. 与柴博合作完成登录注册页面issue 继续完成登录注册页面issue 柴博 ...

  5. BUAA 软工 | 从计算机技术中探索艺术之路

    项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 第一次作业-热身! 我在这个课程的目标是 掌握软件开发方法学和工程学知识 这个作业在哪个具体方面帮 ...

  6. 人人都写过的5个Bug!

    大家好,我是良许. 计算机专业的小伙伴,在学校期间一定学过 C 语言.它是众多高级语言的鼻祖,深入学习这门语言会对计算机原理.操作系统.内存管理等等底层相关的知识会有更深入的了解,所以我在直播的时候, ...

  7. MD5函数(公共方法)

    1 #region MD5函数 2 /// <summary> 3 /// MD5函数 4 /// </summary> 5 /// <param name=" ...

  8. 构建乘积数组 牛客网 剑指Offer

    构建成绩数组 牛客网 剑指Offer 题目描述 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]A[1]...*A[i-1]A[i ...

  9. poj 2724 Purifying Machine(二分图最大匹配)

    题意: 有2^N块奶酪,编号为00...0到11..1. 有一台机器,有N个开关.每个开关可以置0或置1,或者置*.但是规定N个开关中最多只能有一个开关置*. 一旦打开机器的开关,机器将根据N个开关的 ...

  10. 第02课 OpenGL 多边形

    你的第一个多边形: 在第一个教程的基础上,我们添加了一个三角形和一个四边形.也许你认为这很简单,但你已经迈出了一大步,要知道任何在OpenGL中绘制的模型都会被分解为这两种简单的图形.读完了这一课,你 ...