補題解系列,話說這題好久之前做的了的說
首先我們容易得出我們要求的就是糖果比藥片能量大的組數(下文稱此為匹配)為\(\frac\)的方案數
我們發現這個很難求,根據套路這個時候我們應該容斥,求乙個至少或者至多
由於匹配\(i\)組之後剩下隨便放造成的組數顯然不會小於\(i\),因此我們考慮求出匹配的對數至少為\(i\)的方案數
如果我們指導所有數中選出\(i\)個匹配的方案數\(t_i\)的話 匹配的對數至少為\(i\)的方案數就是\(t_i\times(n-i)!\)
那麼我們先考慮求\(t_i\),肯定還是用dp。我們先給糖果和藥片都排序,那麼顯然我們後面列舉的糖果一定能匹配的區間一定覆蓋前面的糖果
設\(f_\)表示前\(i\)個糖果,其中匹配了\(j\)對的方案數,然後我們預處理出\(h_i\)表示第\(i\)個糖果最多能和多少個藥片匹配,則顯然有轉移:
\[f_=f_+[h_i-(j-1)]\times f_
\]那麼最後我們求出的\(f_\)就是\(t_i\)了!
最後乙個問題,我們怎麼得出恰好為\(\frac\)對的方案數?設恰好\(i\)對為\(g_i\),顯然我們可以套路地大力\(o(n^2)\)容斥:
\[g_i=f_\times(n-i)!-\sum_^ c_j^i\times g_j
\]是可以通過此題的(**沒寫)
然後對於這種特殊情況還有更優秀的方法——廣義容斥,式子(非常優美):
\[f_n=\sum_^n c_n^i\times g_i\leftrightarrow g_n=\sum_^n (-1)^c_n^i\times f_i
\]具體證明可以看陳指導的部落格(其實我是懶得打那麼多公式了233),然後:
\[g_}=\sum_}^n (-1)^}c_i^}\times f_\times (n-i)!
\]
#include#include#define ri register int
#define ci const int&
using namespace std;
const int n=2005,mod=1e9+9;
int n,k,a[n],b[n],f[n][n],fact[n],num[n],inv[n],ans;
inline int sum(ci x,ci y)
inline int quick_pow(int x,int p=mod-2,int mul=1)
inline void init(ci n)
inline int c(ci n,ci m)
int main()
bzoj 3622 已經沒有什麼好害怕的了
我好害怕這種題 兩個陣列排序後,處理出next i 表示滿足tang i yao j 的最大的j。f i j 前i種糖果,有j個糖比藥多,不考慮剩餘情況的方案數 也就是剩餘n j個糖果的放法算一種,最後乘上階乘。f i j f i 1 j f i 1 j 1 max next i j 1,0 開始忘...
BZOJ 3622 已經沒有什麼好害怕的了
這名字起的。題意 給出兩數列a,b都有n個元素,元素兩兩互不相同,問有多少種方案使得恰好 a i b j 的數目 a i b j 的數目 k?轉化 恰好有a i b j 的數目 n k 2 如果n k為奇數無解。link here 蒟蒻連普通dp也想不到啊otz 首先將糖果藥片們排序 設糖果i大於的...
BZOJ3622 已經沒有什麼好害怕的了
題意 給定兩個長度為n的互不相同的序列,將其兩兩配對,求有多少種配對使得a i b i 的對數減去其他對數恰好為k。一道經典的計數題,但思路理清後發現並不算難。首先設x為a i 小於b i 的對數。x x k n 2 x n k 所以當n k為奇數,答案為0。先令ne i 表示小於a i 的最後乙個...