USACO 2020 DEC Sleeping Cows P 題解
阿新 • • 發佈:2020-12-24
將牛和牛圈按照升序排序。設z[i]表示第i個牛圈可以和前z[i]頭牛匹配。
從前往後掃描牛圈。dp[i][j][k]表示掃描到第i個牛圈,在前z[i]個牛中,還有j被欽定匹配和i+1~n的牛圈匹配。k表示是否有一個牛被欽定不被比配。
dp[i][j][k]可以擴充套件到dp[i+1][j+l][k'] 考慮編號在(z[i-1],z[i]]裡的牛,假設那個區間裡的牛有l個被匹配。
然後再用dp[i+1][j+1][k]*(j+1)來更新dp[i+1][j][k],表示第i個牛圈和一個牛匹配。
如果有牛被欽定不被匹配,接下來的所有的牛圈都要匹配。
/* { ###################### # Author # # Gary # # 2020 # ###################### */ #include<bits/stdc++.h> #define rb(a,b,c) for(int a=b;a<=c;++a) #define rl(a,b,c) for(int a=b;a>=c;--a) #define LL long long #define IT iterator #define PB push_back #define II(a,b) make_pair(a,b) #define FIR first #define SEC second #define FREO freopen("check.out","w",stdout) #define rep(a,b) for(int a=0;a<b;++a) #define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()) #define random(a) rng()%a #define ALL(a) a.begin(),a.end() #define POB pop_back #define ff fflush(stdout) #define fastio ios::sync_with_stdio(false) #define check_min(a,b) a=min(a,b) #define check_max(a,b) a=max(a,b) using namespace std; //inline int read(){ // int x=0; // char ch=getchar(); // while(ch<'0'||ch>'9'){ // ch=getchar(); // } // while(ch>='0'&&ch<='9'){ // x=(x<<1)+(x<<3)+(ch^48); // ch=getchar(); // } // return x; //} const int INF=0x3f3f3f3f; typedef pair<int,int> mp; /*} */ int n; const int MAXN=3003; const int MOD=1e9+7; int s[MAXN],t[MAXN],z[MAXN],c[MAXN][MAXN],dp[MAXN][MAXN][2]; int main(){ scanf("%d",&n); c[0][0]=1; rb(i,1,n) rb(j,0,n){ c[i][j]=c[i-1][j]; if(j) c[i][j]+=c[i-1][j-1],c[i][j]%=MOD; } rb(i,1,n){ scanf("%d",&s[i]); } rb(i,1,n){ scanf("%d",&t[i]); } sort(s+1,s+1+n); sort(t+1,t+1+n); rb(i,1,n){ z[i]=z[i-1]; while(z[i]!=n&&s[z[i]+1]<=t[i]){ z[i]++; } } dp[0][0][0]=1; rb(i,0,n-1){ rb(j,0,z[i]) rep(flag,2){ rb(k,0,z[i+1]-z[i]){ (dp[i+1][j+k][flag|(k!=(z[i+1]-z[i]))]+=1ll*dp[i][j][flag]*c[z[i+1]-z[i]][k]%MOD)%=MOD; } } rb(j,0,z[i+1]-1){ dp[i+1][j][0]+=1ll*dp[i+1][j+1][0]*(j+1)%MOD; dp[i+1][j][0]%=MOD; dp[i+1][j][1]=1ll*dp[i+1][j+1][1]*(j+1)%MOD; } dp[i+1][z[i+1]][1]=0; } int rest=0; rest+=dp[n][0][0]; rest%=MOD; rest+=dp[n][0][1]; rest%=MOD; cout<<rest<<endl; return 0; }