一粒夸克
2021-08-30 16:21:01
这里提供一种不需要二项式反演的做法。
solution:
令
考虑如何匹配新加进来的糖果和药片:
situation 1:
若
那么我们可以使大于
同时,因为
因此也可以让
这一部分的方案数为:
同时也可以让
因此,对于
situation 2:
若
我们可以让
我们还可以让
因为糖果被排好序了,因此
因此,我们还可以让
因此,对于
递推即可:
code:
#include<bits/stdc++.h>
using namespace std;
int n,k;
int a[2005],b[2005];
long long dp[2005][2005];
const long long md=1e9+9;
int main(){
scanf("%d%d",&n,&k);
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);
dp[0][0]=1;
for(int i=1;i<=n;i++){
if(a[i]>b[i]){
int t=i;
while(t&&a[t]>b[i])t--;
for(int j=0;j<=i;j++){
if(j)dp[i][j]=(2*i-t-j)*dp[i-1][j-1]%md;
dp[i][j]=(dp[i][j]+(j-i+t+1)*dp[i-1][j])%md;
}
}else {
int t=i;
while(t&&b[t]>a[i])t--;
for(int j=0;j<=i;j++){
if(j)dp[i][j]=(t-j+1)*dp[i-1][j-1]%md;
dp[i][j]=(dp[i][j]+(i-t+j)*dp[i-1][j])%md;
}
}
}
printf("%lld\n",dp[n][(n+k)>>1]);
return 0;
}