• BZOJ4710: [Jsoi2011]分特产 组合数学 容斥原理


    • 题意:把M堆特产分给N个同学,要求每个同学至少分到一种特产,共有多少种分法?
    • 把A个球分给B个人的分法种数:(插板法,假设A个球互不相同,依次插入,然后除以全排列去重)

                 C(A,B+A)

    • 把M堆特产分给N个同学分法总数(考虑每堆特产拿出来单独分)

             ∏c(mi,n)

    • 然后因为题目要求每个同学至少分到一种特产,所以用到容斥原理
    •  每个同学至少分到一种特产分法总数  =   没有要求时的分法总数 - 至少有一个同学没有分到特产的分法总数  + 至少有两个同学没有分到特产的分法总数  ……
    • 先预处理出可能用到的C(I,J)的值,然后就乱搞了
    • 代码:
       1 #include <bits/stdc++.h>
       2 #define nmax 2200
       3 #define mod 1000000007
       4  
       5 using namespace std;
       6 typedef long long ll;
       7 int n,m,in;
       8 ll c[nmax][nmax]={0};
       9 ll x[nmax]; //x[i]表示把这些特产只分给i个学生
      10  
      11 void pre(){  //a^b
      12     for (int i=0; i<nmax; i++) c[i][0]=1;
      13     for (int i=1; i<nmax; i++) {
      14             for (int j=1; j<i; j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
      15             c[i][i]=1;
      16     }
      17 }
      18  
      19 int main(){
      20     pre();
      21     cin>>n>>m;
      22     for (int j=1; j<=n; j++) x[j]=1;
      23     for (int i=0; i<m; i++) {
      24         scanf("%d",&in);
      25         for (int j=2; j<=n; j++) {  //枚举学生
      26             x[j]*=c[in+j-1][j-1];
      27             x[j]%=mod;
      28         }
      29     }
      30     for (int j=1; j<=n; j++) { x[j]*=c[n][n-j]; x[j]%=mod; }
      31     //容斥原理
      32     ll ans=0;
      33     for (int i=n; i>=1; i--) {
      34             if( (n-i)&1 ) ans-=x[i]; else ans+=x[i];
      35             ans+=mod;
      36             ans%=mod;
      37     }
      38     cout<<ans<<endl;
      39     return 0;
      40 }
  • 相关阅读:
    MYSQL常用命令集合(转载)
    Spring(七)持久层
    Spring(六)AOP切入方式
    面试题目
    11 集合
    10 常用类
    9 异常机制
    8 面向对象之抽象类+接口+内部类
    7 面向对象的三大特征
    6 面向对象之类和对象
  • 原文地址:https://www.cnblogs.com/jiecaoer/p/11474015.html
Copyright © 2020-2023  润新知