zoukankan      html  css  js  c++  java
  • [CF451E] Devu and Flowers

    题目传送门

    洛谷传送门

     这道题要求的方案数,等价于s个小球(小球相同)、n个盒子(盒子不同)、允许有空盒子的放球的方案数。

    如果没有f[i]的限制,方案数是C(s+n-1,n-1)。

    考虑用总方案数-不合法方案数求出合法方案数。

    可以用一下状压的思想,如果状态某一位是1就代表该处超过了f的限制。

    这样知道了哪几个盒子超出容量了,超出的盒子至少装了f+1个球,先从s里面把f+1减掉。

    剩下的球再往里装的时候,就不受f的限制了。

    超出容量的盒子理应装多于f个,但是我们预先减掉了f+1,所以接下来装多少都行了,因为减掉的f+1已经保证这个盒子超出容量了。

    但是我们这么算会有重复情况,比如说某状态代表1、2两个盒子超出容量了,但是不能保证1和2以外的盒子不超出容量。

    所以1、2的这个状态不是代表1和2超出容量,而是代表至少有1和2超出容量,别的盒子不能保证不超。

    而1 2 3超出容量的、1 2 3 4超出容量的......,等等这些,之后还会再被算一次。

    所以再用一下容斥原理即可。

    顺便提一下,这道题模数比较大,不能线性预处理逆元和阶乘了。

    算组合数的时候,比较大的用卢卡斯定理拆开,小的就暴力算。

     1 #include<cstdio>
     2 typedef long long ll;
     3 const int mod=1000000007;
     4 int n;
     5 ll s;
     6 ll f[25];
     7 
     8 ll ksm(ll b,int p)
     9 {
    10     ll ret=1;
    11     while(p)
    12     {
    13         if(p&1)ret=(ret*b)%mod;
    14         b=(b*b)%mod;
    15         p>>=1;
    16     }
    17     return ret;
    18 }
    19 
    20 ll c(ll cn,ll cm)
    21 {
    22     if(cm>cn)return 0;
    23     if(cn>=mod)
    24         return c(cn%mod,cm%mod)*c(cn/mod,cm/mod)%mod;
    25     if(cm>cn-cm)cm=cn-cm;
    26     ll ca=1,cb=1;
    27     for(ll i=1;i<=cm;i++)
    28         ca=ca*(cn-i+1)%mod,cb=cb*i%mod;
    29     return ca*ksm(cb,mod-2)%mod;
    30 }
    31 
    32 int main()
    33 {
    34     scanf("%d%I64d",&n,&s);
    35     for(int i=1;i<=n;i++)scanf("%I64d",&f[i]);
    36     ll ans=0;
    37     for(int i=0;i<(1<<n);i++)
    38     {
    39         int fl=1,t=i;
    40         ll tot=s;
    41         for(int j=1;j<=n;j++)
    42         {
    43             if(i&(1<<(j-1)))
    44             {
    45                 tot-=(f[j]+1);
    46                 fl=-fl;
    47             }
    48         }
    49         if(tot<0)continue;
    50         ans=((ans+c(tot+n-1,n-1)%mod*fl)%mod+mod)%mod;
    51     }
    52     printf("%I64d",ans);
    53     return 0;
    54 }
  • 相关阅读:
    LeetCode "Super Ugly Number" !
    LeetCode "Count of Smaller Number After Self"
    LeetCode "Binary Tree Vertical Order"
    LeetCode "Sparse Matrix Multiplication"
    LeetCode "Minimum Height Tree" !!
    HackerRank "The Indian Job"
    HackerRank "Poisonous Plants"
    HackerRank "Kundu and Tree" !!
    LeetCode "Best Time to Buy and Sell Stock with Cooldown" !
    HackerRank "AND xor OR"
  • 原文地址:https://www.cnblogs.com/eternhope/p/9887210.html
Copyright © 2011-2022 走看看