• [Lucas定理][隔板法][容斥原理] Codeforces 451E Devu and Flowers


     题解

    • 我们先考虑没有限制的情况怎么求,也就是在n个盒子里取出s个球的方案数,每个盒子可以不取就是隔板法C(n+s-1,n-1)
    • 然后考虑减去每不合法的方案,也就是i个盒子取超的方案数
    • 考虑容斥原理,容易想到容斥系数就是(-1)^i,那么就拿总方案数-1个盒子超+2个盒子超...
    • 然后还是要用Lucas定理来求,因为n和m太大

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #define ll long long
     4 using namespace std;
     5 const ll mo=1e9+7,N=30;
     6 int n;
     7 ll s,r,f[N];
     8 ll ksm(ll a,ll b) { for (r=1;b;b>>=1,a=a*a%mo) if (b&1) r=r*a%mo; return r; }
     9 ll C(ll n,ll m) 
    10 { 
    11     if (m>n) return 0;
    12     if (m>n-m) m=n-m;
    13     ll ans=1ll,fac=1ll;
    14     for (int i=1;i<=m;i++) ans=(ans*(n-i+1))%mo,fac=fac*i%mo;
    15     fac=ksm(fac,mo-2),ans=ans*fac%mo;
    16     return ans;
    17 }
    18 ll lucas(ll n,ll m) { return !m?1:C(n%mo,m%mo)*lucas(n/mo,m/mo)%mo; }
    19 int main()
    20 {
    21     while (scanf("%d%lld",&n,&s)!=EOF)
    22     {
    23         ll ans=0;
    24         for (int i=0;i<n;i++) scanf("%lld",&f[i]);
    25         for (int i=0;i<(1<<n);i++)
    26         {
    27             int k=1; ll p=s;
    28             for (int j=0;j<n;j++) if ((1<<j)&i) k*=-1,p-=f[j]+1;
    29             if (p<0) continue;
    30             (ans+=k*lucas(p+n-1,n-1)%mo)%=mo;
    31         }
    32         ans=(ans+mo)%mo,printf("%lld
    ",ans);
    33     }
    34 }
  • 相关阅读:
    python2和3切换时的几个注意点会报错
    Python异常UnicodeEncodeError 'gbk' codec can't encode character 'xa0'
    python爬虫使用Xpath爬取指定位置的内容
    问题账户需求分析
    2018年春季个人阅读计划
    我们应当怎样做需求分析
    人月神话读后感3
    人月神话读后感2
    线程池
    生产者消费者
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11335099.html
Copyright © 2020-2023  润新知