这题想清楚就不难了hh,下面讲讲思路.
题目:给你n堆花的数量ai,要你从n堆花里选取m朵.问你有多少种选法?(这样当然不能重复hh).
怎么想呢?假设没有我们把m朵花铺平,且加n个隔板.
总方案数是多少?显然C(n+m,n).
不合法的方案数是多少?这个就要用容斥原理了,C(n+m-(ai+1),n).很简单吧hhh
然后我们用二进制枚举就gg了.然后由于容斥原理是有公式的,奇减偶加...emmm真的没了~
代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const ll N=25;
//组合数
ll qp(ll aa,ll bb)
{
    ll res=1;
    aa%=mod;
    while(bb)
    {
        if(bb&1) res=res*aa%mod;
        aa=aa*aa%mod;
        bb>>=1;
    }
    return res;
}

ll C(ll n,ll m)
{
    if(m>n) return 0;
    if(n-m<m) m=n-m;
    ll res=1;
    for(ll i=n;i>n-m;i--)
    {
        res=res*(i%mod)%mod;
    }ll sum=1;
    for(ll i=m;i>=2;i--)
    {
        sum=sum*i%mod;
    }ll lv=qp(sum,mod-2);
    return res*lv%mod;
}

//主函数代码实现

ll a[N];
int main()
{
    ll n,m,ans=0;
    cin>>n>>m;
    for(ll i=0;i<n;i++)    cin>>a[i];
    for(ll i=0;i<(1<<n);i++)//枚举i表示选或不选当前数,假如选的为奇数就减,偶数就加.
    {
        ll cnt=0;ll pos=0;
        for(ll j=0;j<n;j++)
        {
            if(i>>j&1)//假如这一位有.
            {
                cnt++;
                pos=(pos+(a[j]+1))%mod;
            }
        }
        if(cnt%2==1)//奇数
        {
            ans=(ans-C(n+m-1-pos,n-1)+mod)%mod;
        }
        else ans=(ans+C(n+m-1-pos,n-1))%mod;
    }
    cout<<ans<<endl;
    return 0;
}