Devu and Flowers
题意
即给定$n$和$s$,表示有$n$个箱子要取$s$朵花,每个箱子表示一个种类的花,每个箱子中花的数量分别是
$f_{1} , f_{2} , \dots , f_{n}$,求出不同的选取方案
$1 \leq n \leq 20$
$0 \leq s \leq 10^{14}$
$\left.0 \leq f_{i} \leq 10^{12}\right)$
题解
多种集合的组合数
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int N=30,mod=1e9+7; 5 ll f[N]; 6 ll down; 7 ll quick_pow(ll a, ll b){ 8 ll res=1; 9 while(b){ 10 if(b&1) res=res*a%mod; 11 a=a*a%mod; 12 b>>=1; 13 } 14 return res; 15 } 16 ll C(ll a,ll b){ 17 if(a<b) return 0; 18 ll res=1; 19 for(ll i=a;i>a-b;i--) res=i%mod*res%mod; 20 return res*down%mod; 21 } 22 int main(){ 23 ll n, s; 24 cin >> n >> s; 25 for (int i = 0; i < n; i ++ ) cin >> f[i]; 26 down=1; 27 for (ll j = 1; j <= n - 1; j ++ ) down = j * down % mod; 28 down = quick_pow(down, mod - 2); 29 30 int res = 0; 31 for(int i=0;i<1<<n;i++){ 32 ll sign=1; 33 ll a=n+s-1; 34 for(int k=0;k<n;k++){ 35 if(i>>k&1){ 36 sign*=(-1); 37 a-=f[k]+1; 38 } 39 } 40 res = (res + C(a, n-1) * sign) % mod; 41 } 42 cout<<(res+mod)%mod<<endl; 43 }