zoukankan      html  css  js  c++  java
  • [BZOJ3622]已经没有什么好害怕的了(容斥DP)

    给定两个数组a[n]与b[n](数全不相等),两两配对,求“a比b大”的数对比“b比a大”的数对个数多k的配对方案数。

    据说做了这题就没什么题好害怕的了,但感觉实际上这是一个套路题,只是很难想到。

    首先显然“a比b大”的个数是确定的,问题转化成求“a比b大”的数对个数为m的方案数。

    不好算考虑容斥,总结下容斥的一些套路。(From ATP's Blog)

    1.全部-至少一个+至少两个-…=一个也没有的

    2.所有的-一个也没有的=至少有一个的

    3.至少有k个的-C(k+1,k)* 至少有k+1个的+C(k+2,k) *至少有k+2个的…=恰好有k个的

    4.将“强制一部分满足要求,一部分不满足”转化为只强制一部分满足要求,然后容斥

    5.补集转化 Min-Max容斥 与质因子相关的容斥用$mu$做容斥系数。

    (还有一种类似FMT思想的容斥,不过只是用于求解问题中简便使用的,一般不作为容斥方法)

    这题用的是第三种,同样的题可见[BZOJ3198][SDOI2013]Spring(容斥+Hash)

    这样,问题就变成求“a比b大”的数对个数不少于m的方案数。

    将a,b均排序,考虑DP,f[i][j]表示给前i个a中的至少j个安排数值更低的b的方案数。

    则有:f[i][j]=f[i-1][j]+f[i-1][j-1]*(k-(j-1))

    其中k为b中小于a[i]的最后一个数的位置。

    理解起来就是,如果i与k之后的配对,方案数为f[i-1][j],否则i有k-(j-1)种选法。

    问题得解,注意特判n和m不同奇偶,DP转移是特判j=0即可。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
     4 typedef long long ll;
     5 using namespace std;
     6 
     7 const int N=2010;
     8 const ll mod=1000000009;
     9 int n,m;
    10 ll ans;
    11 ll f[N][N],C[N][N],fac[N];
    12 int a[N],b[N];
    13 
    14 int main(){
    15     freopen("bzoj3622.in","r",stdin);
    16     freopen("bzoj3622.out","w",stdout);
    17     scanf("%d%d",&n,&m);
    18     if ((n^m)&1){ puts("0"); return 0; }
    19     m=(n+m)>>1; fac[0]=1;
    20     rep(i,1,n) fac[i]=fac[i-1]*i%mod;
    21     rep(i,1,n) scanf("%d",&a[i]);
    22     rep(i,1,n) scanf("%d",&b[i]);
    23     rep(i,0,n){
    24         C[i][0]=1;
    25         rep(j,1,i) C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
    26     }
    27     sort(a+1,a+n+1); sort(b+1,b+n+1);
    28     f[0][0]=1;
    29     rep(i,1,n){
    30         int k=1; while (k<=n && b[k]<a[i]) k++; k--;
    31         rep(j,1,i) f[i][j]=(f[i-1][j]+f[i-1][j-1]*max(k-j+1,0))%mod;
    32         f[i][0]=f[i-1][0];
    33     }
    34     ll t=1;
    35     rep(i,m,n) f[n][i]=(f[n][i]*fac[n-i])%mod,ans=(ans+t*f[n][i]*C[i][m]%mod+mod)%mod,t=-t;
    36     printf("%lld
    ",(ans+mod)%mod);
    37     return 0;
    38 }
  • 相关阅读:
    java1.5新特性
    [转载]传智播客_SQL入门
    集合类的应用
    多线程的应用
    包的使用
    异常的应用finally与总结
    自定义异常以及runtime类
    异常的处理
    SpringMVC_05 利用spring框架来处理异常
    SpringMVC_04 拦截器 【拦截器的编程步骤】【session复习?】
  • 原文地址:https://www.cnblogs.com/HocRiser/p/9806342.html
Copyright © 2011-2022 走看看