time limit: 10 sec memory limit: 128 mb
submit: 222 solved: 130
[submit][status][discuss]
廢話不多說,反正小w要發喜糖啦!!
小w一共買了n塊喜糖,發給了n個人,每個喜糖有乙個種類。這時,小w突發奇想,如果這n個人相互交換手中的糖,那會有多少種方案使得每個人手中的糖的種類都與原來不同。
兩個方案不同當且僅當,存在乙個人,他手中的糖的種類在兩個方案中不一樣。
第一行,乙個整數n
接下來n行,每行乙個整數,第i個整數ai表示開始時第i個人手中的糖的種類
對於所有資料,1≤ai≤k,k<=n,n<=2000
一行,乙個整數ans,表示方案數模100000000961
1223
310首先我們把每顆糖(第i種糖有$a_i$個)都看成不同的(也就是同種糖的排列順序不同也算進方案)
最後再$ans/=a_i!$,這樣就可以忽略同種糖的問題
一般看到這種題,都是先套路地求至少有$i$個......的方案數,再用容斥求答案。本題也是如此
我們套路地設$f[i][j]$為前$i$種糖,至少$j$個人不合法的方案數
$f[i][j]=\sum_^\ f[i-1][j-k]*c(a_i,k)*a_i!/(a_i-k)!$
對於每個$f[n][i]$,剩下的$n-i$個人可以隨意分糖
所以最終方案數$f[i]=f[n][i]*(n-i)!$
但是肯定有重複算的鴨
所以搞搞容斥統計下就好辣
$ans=\sum_^n(-1)^if[i]$
#include#include#include
using
namespace
std;
typedef
long
long
ll;#define n 2005
const ll p=1e9+9
;int
n,a[n];
ll f[n][n],inv[n],fac[n],ifac[n],ans;
void
prep()
}inline ll c(
int a,int b)
intmain()
BZOJ4665 小w的喜糖 DP
對於這道題,首先每個人的位置並不影響結果 所以我們可以將相同顏色糖果的人放在一塊處理 設 f 表示處理到第 i 種糖果至少有 j 人的糖果和原先的型別相同 列舉當前種類中不滿足要求的個數 則有 f sum f binom dfrac k ans sum n n i c i 表示第 i 種糖的個數,這...
BZOJ4665 小w的喜糖
考慮列舉哪些人一定不合法,那麼方案數可以通過簡單的排列組合算出。於是設 f i j 表示前 i 種糖果,一共有 j 個人一定不合法的方案數,但是這樣並不能保證其他人一定合法,所以需要進行容斥。最後將答案除以每種糖果數量的階乘,即可保證本質不同。時間複雜度 o n 2 includeconst int...
BZOJ 4665 小w的喜糖
題鏈 題解 容斥,dp 令 v i 表示原來擁有i類糖果的人數。乙個套路,首先把每個糖果看成互不相同的,最後再來除以 v i 把同種糖果看成相同的 定義 dp i j 表示前i類糖果,有j個人的糖果和原來的一樣,其他 n j 個人暫時不拿糖果的方案數。這個的轉移如下 對於已經確定的 i,j,列舉乙個...