【BZOJ3622】已经没有什么好害怕的了(动态规划+广义容斥)
大致题意: 有\(n\)个糖果和\(n\)个药片,各有自己的能量。将其两两配对,求糖果比药片能量大的组数恰好比药片比糖果能量大的组数多\(k\)组的方案数。
什么是广义容斥(二项式反演)
我们首先来介绍一下什么是广义容斥。
我们要证明下面这样一个式子:
\]
观察右边这个式子,我们将\(f_n=\sum_{i=0}^nC_n^ig_i\)代入就可以得到:
\]
把\(C_n^i\)移入,可以得到:
\]
通过暴力展开我们可以证明\(C_n^iC_i^j=C_n^jC_{n-j}^{i-j}\),代入得:
\]
然后我们调换\(i\)和\(j\)的枚举顺序,并让\(i\)变为原先的\(n-i-j\)可得:
\]
然后代入二项式定理(因此这又称为二项式反演)\((x+y)^n=\sum_{i=0}^nC_n^ix^iy^{n-i}\)得:
\]
由于式子中出现了一个\(0^{n-j}\),因此只有当\(n-j=0\),即\(n=j\)时,该式才有值,代入得:
\]
因此原式恒成立,得证。
简单转化
恰好多\(k\)组这个条件不是很好求,所以我们可以将其转化一下。
由于总数\(n\)是固定的,所以我们容易求出糖果比药片能量大的组数应为\(\frac{n+k}2\)。
动态规划
接下来,我们就要使用\(DP\)了。
首先,我们把糖果和药片分别按能量排一边序。
则这样可以保证后枚举到的的糖果所能胜过的药片的区间一定能覆盖先枚举到的糖果的区间。
然后,设\(f_{i,j}\)表示糖果匹配到第\(i\)个,且已经与\(j\)个药片匹配的方案数,并设\(g_i\)表示能与第\(i\)个糖果匹配的药片数,则我们可以推出转移方程为:
\]
广义容斥
从前面\(DP\)得到的\(f_{n,i}\),我们可以轻松推得糖果大于药片的对数大于等于\(i\)的方案数。
由于我们已经确定了\(i\)对,而剩下的\((n-i)\)对实际上可以随意匹配,因此便是一个全排列。即:
\]
我们可以设\(F_i\)表示糖果大于药片的对数恰好等于\(i\)的方案数,则可得:
\]
然后用先前提到的广义容斥,就可以得到:
\]
已知糖果比药片能量大的组数应为\(\frac{n+k}2\),则\(F_{\frac{n+k}2}\)即为答案。
而这可以直接求。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 2000
#define X 1000000009
#define Qinv(x) Qpow(x,X-2)
#define Inc(x,y) ((x+=(y))>=X&&(x-=X))
#define C(x,y) (1LL*Fac[x]*Inv[y]%X*Inv[(x)-(y)]%X)
using namespace std;
int n,k,a[N+5],b[N+5],g[N+5],Fac[N+5],Inv[N+5],f[N+5][N+5];
I int Qpow(RI x,RI y) {RI res=1;W(y) y&1&&(res=1LL*res*x%X),x=1LL*x*x%X,y>>=1;return res;}//快速幂
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define pc(c) (C^FS?FO[C++]=c:(fwrite(FO,1,C,stdout),FO[(C=0)++]=c))
#define tn(x) (x<<3)+(x<<1)
#define D isdigit(c=tc())
int T,C;char c,*A,*B,FI[FS],FO[FS],S[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn(x)+(c&15),D);}
Tp I void write(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
I void clear() {fwrite(FO,1,C,stdout),C=0;}
}F;
int main()
{
RI i,j,t,ans=0;for(F.read(n,k),i=1;i<=n;++i) F.read(a[i]);for(i=1;i<=n;++i) F.read(b[i]);//读入数据
for(sort(a+1,a+n+1),sort(b+1,b+n+1),i=1;i<=n;++i) {g[i]=g[i-1];W(g[i]^n&&a[i]>b[g[i]+1]) ++g[i];}//排序,然后求出g[i]
for(f[0][0]=i=1;i<=n;++i) for(j=0;j<=i;++j) f[i][j]=f[i-1][j],j&&Inc(f[i][j],1LL*f[i-1][j-1]*(g[i]-j+1)%X);//DP转移
for(Fac[0]=i=1;i<=n;++i) Fac[i]=1LL*Fac[i-1]*i%X;for(Inv[n]=Qinv(Fac[n]),i=n-1;~i;--i) Inv[i]=1LL*Inv[i+1]*(i+1)%X;//初始化阶乘及阶乘逆元
for(i=t=n+k>>1;i<=n;++i) Inc(ans,1LL*((i^t)&1?X-1:1)*C(i,t)%X*f[n][i]%X*Fac[n-i]%X);//求出最终答案
return F.write(ans),F.clear(),0;//输出答案
}
【BZOJ3622】已经没有什么好害怕的了(动态规划+广义容斥)的更多相关文章
- bzoj3622已经没有什么好害怕的了 dp+组合+容斥(?)
3622: 已经没有什么好害怕的了 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1033 Solved: 480[Submit][Status][ ...
- BZOJ - 3622:已经没有什么好害怕的了 (广义容斥)
[BZOJ3622]已经没有什么好害怕的了 Description Input Output Sample Input 4 2 5 35 15 45 40 20 10 30 Sample Output ...
- 【BZOJ3622】已经没有什么好害怕的了(动态规划,容斥)
[BZOJ3622]已经没有什么好害怕的了(动态规划,容斥) 题面 BZOJ 题解 很明显的,这类问题是要从至少变成恰好的过程,直接容斥即可. 首先我们要求的是(糖果>药片)=(药片>糖果 ...
- BZOJ3622 已经没有什么好害怕的了 动态规划 容斥原理 组合数学
原文链接https://www.cnblogs.com/zhouzhendong/p/9276479.html 题目传送门 - BZOJ3622 题意 给定两个序列 $a,b$ ,各包含 $n$ 个数 ...
- 洛谷P4859 已经没有什么好害怕的了 [DP,容斥]
传送门 思路 大佬都说这是套路题--嘤嘤嘤我又被吊打了\(Q\omega Q\) 显然,这题是要\(DP\)的. 首先思考一下性质: 为了方便,下面令\(k=\frac{n+k}{2}\),即有恰好\ ...
- BZOJ 3622 : 已经没有什么好害怕的了(dp + 广义容斥原理)
今天没听懂 h10 的讲课 但已经没有什么好害怕的了 题意 给你两个序列 \(a,b\) 每个序列共 \(n\) 个数 , 数之间两两不同 问 \(a\) 与 \(b\) 之间有多少配对方案 使得 \ ...
- 【BZOJ3622】已经没有什么好害怕的了 容斥+DP
[BZOJ3622]已经没有什么好害怕的了 Description Input Output Sample Input 4 2 5 35 15 45 40 20 10 30 Sample Output ...
- [BZOJ3622]已经没有什么好害怕的了(容斥DP)
给定两个数组a[n]与b[n](数全不相等),两两配对,求“a比b大”的数对比“b比a大”的数对个数多k的配对方案数. 据说做了这题就没什么题好害怕的了,但感觉实际上这是一个套路题,只是很难想到. 首 ...
- BZOJ3622 已经没有什么好害怕的了 【dp + 二项式反演】
题目链接 BZOJ3622 题解 既已开题 那就已经没有什么好害怕的了 由题目中奇怪的条件我们可以特判掉\(n - k\)为奇数时答案为\(0\) 否则我们要求的就是糖果大于药片恰好有\(\frac{ ...
随机推荐
- Java 字节流和字符流
程序中都是以流的形式进行数据的传输和保存,在java.io包中数据流操作的两大类是字节流和字符流. 1. 字节流 InputStream和OutputStream是所有表示字节流的类的父类,它们都是抽 ...
- 缓冲区 粘包 029 send 和sendall 的区别 find 和 findall 的区别
一.tcp : 属于长连接 与客户端连接了之后 其他客户端需要等待 要连接另外一个 必须优雅的断开前面这个客户的连接. 二.缓冲区 :为了避免网络传输信号不通畅而是程序一直停留在消息发送状态而不向下进 ...
- Rest Framework简介 和 RESTful API 设计指南
使用Django Rest Framework之前我们要先知道,它是什么,能干什么用? Django Rest Framework 是一个强大且灵活的工具包,用以构建Web API 为什么要使用Res ...
- Visio Studio使用总结
1.常用快捷键: 注释:Ctrl+K+C 取消注释:Ctrl+K+U 增加缩进:Table 减少缩进: Table+Shift 格式化文本:A. Ctrl+K+F(选中文本) B. Ctrl+K ...
- 既然有了HBase,为什么还需要Kudu呢?
不多说,直接上干货! 那既然有了HBase,为什么还需要Kudu呢? 简单的说,就是嫌弃HBase在OLAP(联机分析处理)场合,SQL/MR类的批量检索场景中,性能不够好.通常这种海量数据OLAP场 ...
- dos文件格式转换为Unix文件格式
做linux开发的,一般还是在windows上装个虚拟机,在windows上开发, 所以就会出现dos文件与unix文件格式不一致,当windows上的文件在linux上用的时候,经常在每行的末尾会出 ...
- wampserver启动时图标不变绿的解决方法
有2种可能: 1.你安装wamp的时候安装路径中有中文,把路径全部改为英文. 2.其他软件占用了80端口号,解决方法是在服务中找微软的sql server或者其他服务,关掉服务后重启就行了.
- 【转】浅谈https\ssl\数字证书
转载请注明出处:http://www.cnblogs.com/P_Chou/archive/2010/12/27/https-ssl-certification.html 全球可信的SSL数字证书申请 ...
- 关于docker remote api未授权访问漏洞的学习与研究
漏洞介绍: 该未授权访问漏洞是因为docker remote api可以执行docker命令,从官方文档可以看出,该接口是目的是取代docker 命令界面,通过url操作docker. docker ...
- Swift-取消传统For循环
1.取消传统的For循环 传统的for,在swift 3.0 被取消 i++/++i在swift 3.0 被取消 i += 1代替 for var i = 0;i<10;i +=1 { } 2. ...