【BZOJ4710】[Jsoi2011]分特產 組合數+容斥

來源:互聯網
上載者:User

標籤:namespace   long   合數   amp   type   枚舉   數組   mod   clu   

【BZOJ4710】[Jsoi2011]分特產DescriptionJYY 帶隊參加了若干場ACM/ICPC 比賽,帶回了許多土特產,要分給實驗室的同學們。JYY 想知道,把這些特產分給N 個同學,一共有多少種不同的分法?當然,JYY 不希望任何一個同學因為沒有拿到特產而感到失落,所以每個同學都必須至少分得一個特產。例如,JYY 帶來了2 袋麻花和1 袋包子,分給A 和B 兩位同學,那麼共有4 種不同的分配方法:A:麻花,B:麻花、包子A:麻花、麻花,B:包子A:包子,B:麻花、麻花A:麻花、包子,B:麻花Input輸入資料第一行是同學的數量N 和特產的數量M。第二行包含M 個整數,表示每一種特產的數量。N, M 不超過1000,每一種特產的數量不超過1000Output輸出一行,不同分配方案的總數。由於輸出結果可能非常巨大,你只需要輸出最終結果MOD 1,000,000,007 的數值就可以了。Sample Input5 4
1 3 3 5Sample Output384835

題解:組合數還是不夠熟練啊~

顯然要容斥,設f[i]表示將所有物品都只分給i個人(不一定全都分到)的方案數,那麼分開考慮每個物品,如果物品j的數量為v,那麼方案數等價於將v個物品分成i個子集的方案數,即f[i]*=C(v+i-1,i-1)。

求出了f數組,考慮容斥,ans=至少0人未分到-至少1人未分到+至少2人未分到...

於是枚舉有k個人未分到,ans+=(-1)^k*C(n,k)*f[n-k]。

 

#include <cstdio>#include <cstring>#include <iostream>using namespace std;typedef long long ll;const ll P=1000000007;const int maxn=1000010;int n,m,tot;ll ans;ll jc[maxn],jcc[maxn],ine[maxn],f[maxn];int v[maxn];ll c(int a,int b){return jc[a]*jcc[b]%P*jcc[a-b]%P;}ll pm(ll x,ll y){ll z=1;while(y){if(y&1)z=z*x%P;x=x*x%P,y>>=1;}return z;}int main(){scanf("%d%d",&n,&m);int i,j;for(i=1;i<=m;i++)scanf("%d",&v[i]),tot+=v[i];if(n>tot){printf("0");return 0;}ine[1]=ine[0]=jc[1]=jc[0]=jcc[1]=jcc[0]=1;for(i=2;i<=tot;i++)ine[i]=(P-(P/i)*ine[P%i])%P,jc[i]=jc[i-1]*i%P,jcc[i]=jcc[i-1]*ine[i]%P;for(i=1;i<=n;i++)f[i]=1;for(i=1;i<=m;i++)for(j=1;j<=n;j++)f[j]=f[j]*c(v[i]+j-1,j-1)%P;for(i=0;i<n;i++)ans=(ans+((i&1)?-1:1)*c(n,i)%P*f[n-i]%P+P)%P;printf("%lld\n",ans%P);return 0;}//2 2 1 2

 

【BZOJ4710】[Jsoi2011]分特產 組合數+容斥

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

Tags Index: