正题
P7154
题目大意
有n头牛和n个牛棚,每头牛可以进入体积大于等于该牛的牛棚,当一个所有未进入牛棚的牛都不能再进时,称为极大的匹配,问你有多少种极大的匹配
解题思路
先把牛棚和牛放到一起,然后按体积排序
那么考虑DP
如果一个牛棚没有选,那么后面的牛必须全部匹配,否则该牛棚可以与其匹配
对于一头牛,如果不是必须匹配,那前面的牛棚就全选了,该牛就可选可不选,否则必须选
那么设fi,j,1/0f_{i,j,1/0}fi,j,1/0表示前i个单位,还有j个牛棚,后面的牛必须选/不一定要选的方案数,然后DP即可
code
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define wyc 1000000007
#define N 3030
using namespace std;
int n,now,f[N<<1][N][2];
struct node
{int s,v;
}a[N<<1];
bool cmp(node x,node y)
{return x.s>y.s||x.s==y.s&&x.v>y.v;
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;++i){scanf("%d",&a[i].s);a[i].v=0;}for(int i=n+1;i<=n*2;++i){scanf("%d",&a[i].s);a[i].v=1;}sort(a+1,a+1+n*2,cmp);now=0;f[0][0][0]=1;for(int i=1;i<=n*2;++i){if(!a[i].v){for(int j=0;j<=now;++j){(f[i][j][0]+=f[i-1][j][0])%=wyc;;//可以不选if(j){(f[i][j-1][0]+=1ll*f[i-1][j][0]*j%wyc)%=wyc;//也可以选(f[i][j-1][1]+=1ll*f[i-1][j][1]*j%wyc)%=wyc;//必须选}}}else{for(int j=0;j<=now;++j){(f[i][j][1]+=(f[i-1][j][0]+f[i-1][j][1])%wyc)%=wyc;//不选(f[i][j+1][0]+=f[i-1][j][0])%=wyc;(f[i][j+1][1]+=f[i-1][j][1])%=wyc;}now++;}}printf("%d",(f[n*2][0][0]+f[n*2][0][1])%wyc);return 0;
}