【做题】CF285E. Positions in Permutations——dp+容斥
题意:求所有长度为\(n\)的排列\(p\)中,有多少个满足:对于所有\(i \,(1 \leq i \leq n)\),其中恰好有\(k\)个满足\(|p_i - i| = 1\)。答案对\(10^9 + 7\)取模。
\(n \leq 10^3\)
首先,让我们考虑这个类似反演的结论:
对于\(F(n)\)和\(f(n)\),则满足
\[F(n) = \sum_{k \geq n}{{k}\choose{n}}f(k) \iff f(n) = \sum_{k \geq n}(-1)^{k-n}{{k}\choose{n}}F(k)
\]
对于充分性,我们有
= & \sum_{k \geq n}(-1)^{k-n}{{k}\choose{n}} \sum_{j \geq k} {{j}\choose{k}} f(j) \\
= & \sum_{j \geq n} f(j) {{j}\choose{n}} \sum_{n \leq k \leq j} (-1)^{k-n} {{j-n}\choose{k-n}} \\
= & \sum_{j \geq n} f(j) {{j}\choose{n}} \sum_{0 \leq k \leq j-n} (-1)^k {{j-n}\choose{k}} \\
= & \sum_{j \geq n} f(j) {{j}\choose{n}} (1-1)^{j-n} \\
= & f(n)\end{aligned}
\]
而对于必要性,我们也能给出类似的证明。
观察这个结论,不难发现,我们平时使用的容斥就是这个结论求\(f(0)\)时的特殊情况。而现在我们要求的是\(f(k)\),问题就变成了把所有\(F(n)\)都求出来。
\(F(n)\)的定义正对应了我们求至少有\(k\)个的情况总数时,重复统计所得到的结果。这使得它可以比较容易地求出。
我们考虑权值和位置表示为二分图的形式,那么问题就在于求二分图恰好有\(k\)个匹配的方案数。考虑dp。设dp[i,j,a,b]表示当前匹配到第\(i\)个权值和位置,已经有\(j\)个匹配,并且\(a\)和\(b\)分别表示第\(i\)个位置与权值是否已经与编号更小的权值与位置匹配。通过枚举\(a\)和\(b\),很容易能得到dp的转移。当然,最后的答案还要乘以一个阶乘。
时间复杂度\(O(n^2)\)。
#include <bits/stdc++.h>
using namespace std;
const int N = 1010, MOD = 1000000007;
typedef long long ll;
ll power(ll a,int b) {
ll res = 1;
while (b) {
if (b&1) res = 1ll * res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}
int n,k;
ll dp[N][N][2][2],jc[N],inv[N],ans;
ll comb(int a,int b) {
if (a < 0 || b < 0 || a < b)
return 0;
return jc[a] * inv[b] % MOD * inv[a-b] % MOD;
}
int main() {
scanf("%d%d",&n,&k);
dp[0][0][1][1] = 1;
for (int i = 1 ; i <= n ; ++ i)
for (int j = 0 ; j <= n ; ++ j) {
(dp[i][j][0][0] = dp[i-1][j][0][0] + dp[i-1][j][1][0] + dp[i-1][j][0][1] + dp[i-1][j][1][1]) %= MOD;
if (j >= 1) {
(dp[i][j][1][0] = dp[i-1][j-1][0][0] + dp[i-1][j-1][1][0]) %= MOD;
(dp[i][j][0][1] = dp[i-1][j-1][0][0] + dp[i-1][j-1][0][1]) %= MOD;
}
if (j >= 2)
dp[i][j][1][1] = dp[i-1][j-2][0][0];
}
jc[0] = 1;
for (int i = 1 ; i <= n ; ++ i)
jc[i] = 1ll * i * jc[i-1] % MOD;
inv[n] = power(jc[n],MOD-2);
for (int i = n-1 ; i >= 0 ; -- i)
inv[i] = 1ll * inv[i+1] * (i+1) % MOD;
for (int j = k, p = 1 ; j <= n ; ++ j, p = -p) {
ll v = 1ll * jc[n-j] * (dp[n][j][0][0] + dp[n][j][1][0] + dp[n][j][0][1] + dp[n][j][1][1]) % MOD;
(ans += p * comb(j,k) * v % MOD) %= MOD;
}
ans = (ans % MOD + MOD) % MOD;
cout << ans << endl;
return 0;
}
小结:这种类似于反演的东西是很多组合问题的通用方法,希望自己能实现灵活的运用。
【做题】CF285E. Positions in Permutations——dp+容斥的更多相关文章
- CF285E Positions in Permutations(dp+容斥)
题意,给定n,k,求有多少排列是的 | p[i]-i |=1 的数量为k. Solution 直接dp会有很大的后效性. 所以我们考虑固定k个数字使得它们是合法的,所以我们设dp[i][j][0/1] ...
- 【CF715E】Complete the Permutations(容斥,第一类斯特林数)
[CF715E]Complete the Permutations(容斥,第一类斯特林数) 题面 CF 洛谷 给定两个排列\(p,q\),但是其中有些位置未知,用\(0\)表示. 现在让你补全两个排列 ...
- [Luogu P1450] [HAOI2008]硬币购物 背包DP+容斥
题面 传送门:https://www.luogu.org/problemnew/show/P1450 Solution 这是一道很有意思的在背包里面做容斥的题目. 首先,我们可以很轻松地想到暴力做背包 ...
- bzoj 3622 DP + 容斥
LINK 题意:给出n,k,有a,b两种值,a和b间互相配对,求$a>b$的配对组数-b>a的配对组数恰好等于k的情况有多少种. 思路:粗看会想这是道容斥组合题,但关键在于如何得到每个a[ ...
- 【BZOJ 4665】 4665: 小w的喜糖 (DP+容斥)
4665: 小w的喜糖 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 94 Solved: 53 Description 废话不多说,反正小w要发喜 ...
- CodeForces - 285E: Positions in Permutations(DP+组合数+容斥)
Permutation p is an ordered set of integers p1, p2, ..., pn, consisting of n distinct positive in ...
- CDOJ 1294 天行廖的游戏 dp 容斥
天行廖的游戏 题目连接: http://acm.uestc.edu.cn/#/problem/show/1294 Description 天行健,君子以自强不息.地势坤,廖爷以厚德载物 一日在喵哈哈村 ...
- codeforces 342D Xenia and Dominoes(状压dp+容斥)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud D. Xenia and Dominoes Xenia likes puzzles ...
- BZOJ.4559.[JLOI2016]成绩比较(DP/容斥 拉格朗日插值)
BZOJ 洛谷 为什么已经9点了...我写了多久... 求方案数,考虑DP... \(f[i][j]\)表示到第\(i\)门课,还有\(j\)人会被碾压的方案数. 那么\[f[i][j]=\sum_{ ...
随机推荐
- mysql避免脏读
mysql避免脏读 在MySQL的InnoDB中,预设的Tansaction isolation level 为REPEATABLE READ(可重读) 在SELECT 的读取锁定主要分为两种方式 ...
- 转:C# 使用资源文件 Resource.resx 的方法
在写程序时, 可以把用到的 图标,图片,声音等外部资源,放在一个 .resx (资源文件)中. 这样的好处是不用考虑什么路径的问题.而且还对资源有保护的做用. 1.创建一个 ResourceFile ...
- Google Analytics for Firebase 是一款免费的应用评估解决方案,可提供关于应用使用和用户互动情况的数据分析
Google Analytics for Firebase Google Analytics for Firebase 是一款免费的应用评估解决方案,可提供关于应用使用和用户互动情况的数据分析.Fir ...
- mongodb安全权限设定
mongodb安全权限设定 如何防范此类攻击? 做好访问认证.打开你的MongoDB配置文件(.conf),设置为auth=true 做好防火墙设置.建议管理者关闭27017端口的访问. Bind_i ...
- activiti 报 next dbid
记录一下吧. 今天将生产环境的几个服务节点改成集群模式,其中包含activiti审批服务节点,其中各个服务几点间数据通信采用MQ(与本文无关). 然后报出如题错误. 究其原因就是,在启动activit ...
- 通过junit/TestNG+java 实现自动化测试
第一步 安装JDK JDk1.7. 下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-188026 ...
- JSP Servlet javaben
CLASSPATH=D:\Dev\jdk\lib\tools.jar;D:\Dev\jdk\lib\dt.jarJAVA_HOME=D:\Dev\jdkPath=%JAVA_HOME%\bin 一:T ...
- socket编程-阻塞和非阻塞
转自:https://www.cnblogs.com/sunziying/p/6501045.html 建立连接 阻塞方式下,connect首先发送SYN请求道服务器,当客户端收到服务器返回的SYN的 ...
- Linux进程内存分析pmap命令
转自: http://blog.csdn.net/u013982161/article/details/52654256 名称: pmap - report memory map of a proce ...
- go开发工具及安装使用(Liteide)Liteide-centos6.8 安装
开发工具介绍 LiteIDE https://github.com/visualfc/liteide/blob/master/liteidex/deploy/welcome/zh_CN/readme. ...