Bzoj4710--Jsoi2011分特產

來源:互聯網
上載者:User

標籤:

組合計數+容斥原理的題目

考慮對於每一類特產分給所有人有多少種方式,就是把每類特產分給所有人的方案數乘積

把x個物品分給n個人的方案數可以看成n-1個分隔字元和x個物品的排列數,即為n-1+x個物品中選出x個物品的方案數,即C(x,x+n-1)

但是這樣會把不合法的狀態也算入答案,所以可以容斥一波

n個人中有a個人沒分到東西的方案數即為把x個物品分給n-a個人的方案數,最後再乘上n個人中選a個人的方案數即可

代碼:

#include<bits/stdc++.h>#define INF 1000000000#define LNF 100000000000000ll#define eps 1e-9#define LL long long#define MOD 1000000007inline int _max(int a,int b) {return a>b?a:b;}inline double _fabs(double a) {return a>0?a:-a;}using namespace std;#define MAXN 1005#define MAXM 30005LL C[MAXN*2][MAXN*2],ans;int n,m,a[MAXN],mx;void Get_C() {    int r=n+mx-1;    for(int i=0;i<=r;i++) C[i][0]=1;    for(int i=0;i<=r;i++) C[0][i]=1;    for(int i=1;i<=r;i++) for(int j=1;j<=r;j++)         C[i][j]=(C[i-1][j]+C[i][j-1])%MOD;}LL comp(int v) {    LL ret=C[v][n-v];if(v&1) ret=-ret;    for(int i=1;i<=m;i++)         ret=ret*C[a[i]][n-1-v]%MOD;    return ret;}int main() {    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++) scanf("%d",&a[i]),mx=_max(mx,a[i]);    Get_C();    for(int i=0;i<=n;i++) {        ans=(ans+comp(i))%MOD;        if(ans<0) ans+=MOD*(-ans/MOD+1);    }    cout<<ans<<endl;    return 0;}

 

Bzoj4710--Jsoi2011分特產

聯繫我們

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

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

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.