Devu 有 n 个花瓶,第 ii 个花瓶里有 fi 朵花。他现在要选择 s 朵花。
你需要求出有多少种方案。两种方案不同当且仅当两种方案中至少有一个花瓶选择花的数量不同
可重复集的组合数 Ce( n,m) = C(m-1,m+n-1 )
namo用容斥原理
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int M = 1<<20 ,mod=1e9+7;
#define int long long
#define ll long long
int a[25],f[M];
int fac[22];
int k;
ll r,n[25],inv[25];
ll pow(ll a,ll b,ll p){
ll ans=1;
while(b){
if (b%2) ans=(ans*a)%p;
b/=2;
a=(a*a)%p;
}
return ans;
}
void get_inv(ll n,ll p){
inv[1]=1;
for (ll i=2;i<=n;i++){
inv[i]=inv[p%i]*(p-p/i)%p;
}
}
int C(ll y,ll x){
if (y<0||x<0||y<x) return 0;
y%=mod;
if (y==0 || x==0) return 1;
ll ans=1;
for (int i=0;i<x;i++){
ans=1ll*ans*(y-i)%mod;
}
for (int i=1;i<=x;i++){
ans=1ll*ans*inv[i]%mod;
}
return ans;
}
signed main() {
int n,m;
get_inv(20,mod);
cin>>m>>n;
fac[0]=1;for(int i=1;i<20;i++) fac[i]=fac[i-1]*i ;
for(int i=1;i<=m;i++) cin>>a[i];
int ans=C(m+n-1,m-1);
for(int j=1;j<(1<<m);j++){
int t=m+n, cnt=0;
for(int i=0;i<m;i++){
if((j>>i)&1) cnt++, t-=a[i+1];//
}
t-=cnt+1;
if(cnt&1) ans=(ans-C(t,m-1))%mod ;
else ans=ans+C(t,m-1)%mod ;
}
cout<<(ans+mod)%mod;
}
浙公网安备 33010602011771号