bzoj 3622: 已经没有什么好害怕的了

3622: 已经没有什么好害怕的了

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1088  Solved: 509
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

4 2
5 35 15 45
40 20 10 30

Sample Output

4

HINT

 


输入的2*n个数字保证全不相同。


还有输入应该是第二行是糖果,第三行是药片
要用到二项式反演
#include<iostream>
#include<cstdio>
#include<algorithm>
#define maxn 2010
#define mod 1000000009
using namespace std;
int n,m,a[maxn],b[maxn],nxt[maxn];
long long f[maxn][maxn],dp[maxn],c[maxn][maxn],fac[maxn];
void prepare(){
    for(int i=0;i<=n;i++)c[i][0]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
        c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
    fac[1]=1;
    for(int i=2;i<=n;i++)fac[i]=fac[i-1]*i%mod;
}
int main(){
    scanf("%d%d",&n,&m);m=(m+n)/2;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)scanf("%d",&b[i]);
    sort(a+1,a+n+1);sort(b+1,b+n+1);
    for(int i=1,j=1;i<=n;i++){
        while(j<=n&&b[j]<a[i])j++;
        nxt[i]=j-1;
    }
    prepare();
    for(int i=0;i<=n;i++)f[i][0]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            f[i][j]=(f[i-1][j]+f[i-1][j-1]*max(nxt[i]-j+1,0))%mod;
    for(int i=n;i>=m;i--){
        dp[i]=f[n][i]*fac[n-i]%mod;
        for(int j=i+1;j<=n;j++)
            dp[i]=((dp[i]-dp[j]*c[j][i]%mod)%mod+mod)%mod;
    }
    cout<<dp[m]<<endl;
    return 0;
}

 

posted @ 2018-01-07 19:53  Echo宝贝儿  阅读(202)  评论(0编辑  收藏  举报