码迷,mamicode.com
首页 > 其他好文 > 详细

已经没有什么好害怕的了

时间:2019-11-21 12:10:59      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:ret   答案   using   print   for   图片   amp   alt   def   

有糖果和药片各n个。糖果ii有能量ai,药片i有能量bi。

你需要将药片和糖果两两配对,求有多少种方案满足糖果比药片能量大的组数减去药片比糖果能量大的组数恰好为k。
保证所有的能量两两不同,答案对109+9取模。
Input Format#
第一行两个整数n,k
第二行n个整数,表示糖果的能量。
第三行n个整数,表示药片的能量。
Output Format#
输出一行一个整数,表示方案数。

Sample Input#

4 2
5 35 15 45
40 20 10 30
Sample Output#

4

技术图片

题意:给定a数组和b数组,大小都为N,现在让你两两配对,使得a>b个个数=(N+K)/2; a<b的个数=(N-K)/2;
思路:用容斥来求。 我们假设a>b为A情况,a<b为B情况。先让ab数组分别排序;
f[i][j]表示前i个a数组至少存在j个A情况的方案数,那么可以得到f的递推式。 最后用容斥来累加答案。
推荐CQZhangYU的博客。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=2010;
const int Mod=1e9+9;
int C[maxn][maxn],f[maxn][maxn],a[maxn],b[maxn],jc[maxn],ans;
int main()
{
    int N,K; scanf("%d%d",&N,&K);
    jc[0]=1; 
    rep(i,1,N) 
    jc[i]=(ll)jc[i-1]*i%Mod;
    rep(i,0,N)
    {
        C[i][0]=1;
        rep(j,1,i) 
           C[i][j]=(C[i-1][j]+C[i-1][j-1])%Mod;
    }
    rep(i,1,N) 
        scanf("%d",&a[i]);
    rep(i,1,N) 
        scanf("%d",&b[i]);
    sort(a+1,a+N+1) ;
    sort(b+1,b+N+1);
    f[0][0]=1;
    rep(i,1,N) //阶段 
    {
        int pos=upper_bound(b+1,b+N+1,a[i])-b; 
        pos--;
        rep(j,1,i)//存在J种a这样的情况 
        {
            f[i][j]=(f[i-1][j]+(ll)f[i-1][j-1]*max(pos-j+1,0)%Mod)%Mod;
        }
        f[i][0]=f[i-1][0];
    }
    if((N+K)%2==1) 
        return puts("0"),0;
    K=(N+K)/2;
    rep(i,K,N)
    {
        f[N][i]=(ll)f[N][i]*jc[N-i]%Mod;
        if((i-K)&1) 
            ans=((ans-(ll)f[N][i]*C[i][K]%Mod)%Mod+Mod)%Mod;
        else 
            ans=(ans+(ll)f[N][i]*C[i][K]%Mod)%Mod;
    }
    printf("%lld\n",(ans%Mod+Mod)%Mod);
    return 0;
}

 

已经没有什么好害怕的了

标签:ret   答案   using   print   for   图片   amp   alt   def   

原文地址:https://www.cnblogs.com/cutemush/p/11904402.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!