BZOJ 3622 已经没有什么好害怕的了
2017-01-18 20:51
387 查看
DP+容斥
然而这题还是令我很害怕。
最值问题的DP一般考虑排序之后从小到大或从大到小,一个一个地考虑。
对于这题,对A,B排序,记next[i]=j,表示最大的j满足B[j] < A[i],不难想到方程f[i][j]表示做到A的第i个,其中已经有j对满足A>B,然后转移
f[i][j] = f[i-1][j] + f[i-1][j-1] * (next[i] - j + 1)
但是这是错的,因为我们只钦定了有j对大于,并不能确定剩下的n-j对就一定是小于。一般想到这里就觉得这个DP没用了。然而这题妙在可以直接容斥减去不合法状态。。。
记g[i][j]表示做到A的第i位,恰好有j对满足A>B。
我们考虑f
[j]中重复出现的东西到底出现了多少次。
对于恰好j对的方案,一定是不重不漏地都被统计了,因为这j对一定恰好被钦定了。
对于恰好j+1的方案,有C(j+1,j)种方案能选出j个来被钦定,因此它被统计了C(j+1,j)。
实际上恰好k的方案就统计了C(k,j)次。我们把g乘上这个系数减掉即可。
然而这题还是令我很害怕。
最值问题的DP一般考虑排序之后从小到大或从大到小,一个一个地考虑。
对于这题,对A,B排序,记next[i]=j,表示最大的j满足B[j] < A[i],不难想到方程f[i][j]表示做到A的第i个,其中已经有j对满足A>B,然后转移
f[i][j] = f[i-1][j] + f[i-1][j-1] * (next[i] - j + 1)
但是这是错的,因为我们只钦定了有j对大于,并不能确定剩下的n-j对就一定是小于。一般想到这里就觉得这个DP没用了。然而这题妙在可以直接容斥减去不合法状态。。。
记g[i][j]表示做到A的第i位,恰好有j对满足A>B。
我们考虑f
[j]中重复出现的东西到底出现了多少次。
对于恰好j对的方案,一定是不重不漏地都被统计了,因为这j对一定恰好被钦定了。
对于恰好j+1的方案,有C(j+1,j)种方案能选出j个来被钦定,因此它被统计了C(j+1,j)。
实际上恰好k的方案就统计了C(k,j)次。我们把g乘上这个系数减掉即可。
#include<cstdio> #include<algorithm> #define MOD 1000000009 #define N 2005 using namespace std; namespace runzhe2000 { typedef long long ll; const int INF = 1<<30; int a , b , next , f , g , c , n, k, fac ; void init() { c[0][0] = 1; fac[0] = 1; for(int i = 1; i <= n; i++) { c[i][0] = 1; for(int j = 1; j <= i; j++) c[i][j] = (c[i-1][j] + c[i-1][j-1]) % MOD; fac[i] = (ll)fac[i-1] * i % MOD; } } void main() { scanf("%d%d",&n,&k); if((n+k)&1){puts("0"); return;} init(); for(int i = 1; i <= n; i++) scanf("%d",&a[i]); sort(a+1, a+1+n); for(int i = 1; i <= n; i++) scanf("%d",&b[i]); sort(b+1, b+1+n); b[n+1] = INF; for(int i = 1; i <= n; i++) { int p = next[i-1]; for(; b[p+1] < a[i]; p++); next[i] = p; } f[0][0] = 1; for(int i = 1; i <= n; i++) { f[i][0] = 1; for(int j = 1; j <= i; j++) f[i][j] = (f[i-1][j] + (ll)f[i-1][j-1] * (next[i] - j + 1)) % MOD; } for(int i = n; i; i--) { f [i] = (ll)f [i] * fac[n-i] % MOD; for(int j = n; j > i; j--) { f [i] = (f [i] - (ll)g[j] * c[j][i]) % MOD; } g[i] = f [i]; } printf("%d\n",(g[(n+k)/2]+MOD) % MOD); } } int main() { runzhe2000::main(); }
相关文章推荐
- Spark商业案例与性能调优实战100课》第11课:商业案例之通过纯粹通过DataFrame分析大数据电影点评系仿QQ和微信、淘宝等用户群分析与实战
- Android之开始启程
- PAT1006题解
- 【WC模拟】优美的树
- 计算机中那些事儿(十):资料管理一些建议---实践篇
- 二、java数据类型转换
- [TOP10]十大渗透测试演练系统
- AC Dream1069
- php源码zend_do_begin_namespace函数详解
- 设计模式之模板方法模式(java)
- CTabCtrl设值选项卡标签宽度的方法
- oracle学习总结---plsql基本语法
- Linux学习笔记——例说makefile 增加系统共享库
- poj 3087 直接模拟
- poj 3087 直接模拟
- poj 3087 直接模拟
- poj 3087 直接模拟
- poj 3087 直接模拟
- poj 3087 直接模拟
- poj 3087 直接模拟