日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

题解-bzoj4221 JOI2012kangaroo

發布時間:2024/4/15 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 题解-bzoj4221 JOI2012kangaroo 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Problem

bzoj

題意:給定\(n\)只袋鼠,每只袋鼠有倆屬性\(a,b\),若\(a_i\leq b_j\),則\(i\)是可以被\(j\)放置在袋子里的,求經過一系列放置操作后無法進行操作時的狀態有多少種可能(每只袋鼠只能被一只袋鼠放在袋子里,同時也只能放一只袋鼠在袋子里)

\(n\leq 300,\forall i\in[1,n]a_i\geq b_i\)

Solution

將每只袋鼠拆成出點和入點后做匹配,相當于剩余未匹配點中\(\min a\geq \max b\)的匹配方案數

由于\(a_i\geq b_i\)保證不可能自己連向自己,相當于是自由匹配,所以點與點之間的順序是沒有任何關系的,考慮將兩者從大到小排序

\(f[i][j][k]\)表示當前考慮到第\(i\)只袋鼠的體積,這\(i\)只袋鼠中有\(j\)只已經被匹配,設\(t\)為第\(i\)只袋鼠能塞進的最小口袋(\(t\)也遞增),則\(k\)表示前\(t\)個口袋中與袋鼠\([i+1,n]\)中匹配的數量

考慮到在定義下的\(f[i][j][k]\)中,這\(j\)只已經被匹配的袋鼠所對應的口袋一定在區間\([1,t]\)中,所以口袋\([1,t]\)分為三類:

  • ① 和區間\([1,i]\)內共\(j\)只袋鼠匹配的口袋,共\(j\)
  • ② 和區間\([i+1,n]\)內共\(k\)只袋鼠匹配的口袋,共\(k\)
  • ③ 自由節點,尚未匹配,共\(t-j-k\)

理順了這些可以得到以下仨轉移式(一般自己寫可能會有情況缺漏,反正我是想了很久)

\[f[i][j][t-j]+=f[i-1][j][k]\]

\[f[i][j+1][k]+=f[i-1][j][k]\cdot (t-j-k)\]

\[f[i][j+1][k-1]+=f[i-1][j][k]\cdot k\]

自然統計答案

\[Ans=\sum_{i=0}^nf[n][i][0]\]

Code

#include <bits/stdc++.h> using namespace std; #define rg registertemplate <typename _Tp> inline _Tp read(_Tp&x){char c11=getchar();x=0;while(!isdigit(c11))c11=getchar();while(isdigit(c11))x=x*10+c11-'0',c11=getchar();return x; }const int N=301,p=1e9+7; int f[N][N][N],a[N],b[N]; int n,ans;template <typename _tp> inline void pls(int&A,_tp B){A=A+B<p?A+B:A+B-p;} inline bool cmp(const int&A,const int&B){return A>B;}void init();void work();void print(); int main(){init();work();print();return 0;}void work(){f[0][0][0]=1;for(rg int i=1,t=1;i<=n;++i){if(!t)++t;while(a[i]<b[t]&&t<=n)++t;--t;for(rg int j=0;j<i;++j)for(rg int k=0;k+j<=t;++k){pls(f[i][j][t-j],f[i-1][j][k]);pls(f[i][j+1][k],1ll*f[i-1][j][k]*(t-j-k)%p);if(k)pls(f[i][j+1][k-1],1ll*f[i-1][j][k]*k%p);}} }void print(){for(rg int i=0;i<=n;++i)pls(ans,f[n][i][0]);printf("%d\n",ans); }void init(){read(n);for(rg int i=1;i<=n;++i)read(a[i]),read(b[i]);sort(a+1,a+n+1,cmp);sort(b+1,b+n+1,cmp); }

轉載于:https://www.cnblogs.com/penth/p/9779072.html

總結

以上是生活随笔為你收集整理的题解-bzoj4221 JOI2012kangaroo的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。