题意:每个箱子里有\( f[i] \)种颜色相同的花,现在要取出\( s \)朵花,问一共有多少种颜色组合
首先枚举\( 2^n \)种不满足条件的情况,对于一个不被满足的盒子,我们至少拿出\( f[i]+1 \)朵花。
然后进行容斥,不满足奇数个条件的减去,不满足偶数个条件的加上
#include<iostream>
#include<cstdio>
using namespace std;
const int N=25,mod=1e9+7;
int n;
long long s,f[N];
long long ksm(long long a,long long b)
{
long long r=1ll;
while(b)
{
if(b&1)
r=r*a%mod;
a=a*a%mod;
b>>=1;
}
return r;
}
long long C(long long a,long long b)
{
if(a<b)
return 0;
b=(b>a-b)?a-b:b;
long long u=1ll,d=1ll;
for(long long i=0;i<b;i++)
{
u=u*(a-i)%mod;
d=d*(i+1)%mod;
}
return u*ksm(d,mod-2)%mod;
}
long long lucas(long long a,long long b)
{
return !b?1:C(a%mod,b%mod)*lucas(a/mod,b/mod)%mod;
}
int main()
{
scanf("%d%I64d",&n,&s);
for(int i=1;i<=n;i++)
scanf("%I64d",&f[i]);
long long ans=0ll;
for(int i=0;i<(1<<n);i++)
{
long long t=1ll,sum=s;
for(int j=1;j<=n;j++)
if(i&(1<<(j-1)))
{
sum-=f[j]+1;
t*=-1;
}
if(sum<0)
continue;
ans+=t*lucas(sum+n-1,n-1);
}
printf("%I64d\n",(ans%mod+mod)%mod);
return 0;
}