题目描述
John 得到了 n 罐糖果。不同的糖果罐,糖果的种类不同(即同一个糖果罐里的糖果种类是相同的,不同的糖果罐里的糖果的种类是不同的)。第 i 个糖果罐里有 mi 个糖果。John 决定吃掉一些糖果,他想吃掉至少 a 个糖果,但不超过 b 个。问题是 John 无法确定吃多少个糖果和每种糖果各吃几个。有多少种方法可以做这件事呢?
输入格式
输入共 n+1 行:
第一行读入 n,a,b。
接下来 n行,一行一个数,代表 mi。
输出格式
仅一行,表示 John 能够选择的满足以上条件的吃掉糖果的方法数,答案对 2004 取模。
输入输出样例
输入 #1
2 1 3 3 5输出 #1
9说明/提示
数据范围及限制
对于 100\%100% 的数据,保证1≤n≤10,0≤a≤b≤10^7,0≤mi≤10^6。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod= 2004;
const ll N = 1e7 + 5;
#define ls i<<1
#define rs i<<1|1
ll n,a,b,f[15],ans,yz=1;
ll C(ll n,ll m)
{
if(n<m)return 0;
ll ans=1,p=mod*yz;
for(ll i=n-m+1; i<=n; ++i)ans=ans*i%p;
return (ans/yz)%mod;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _=1;//cin>>_;
while(_--)
{
cin>>n>>a>>b;
for(int i=0; i<n; ++i)cin>>f[i],yz*=(i+1);
for(int i=0; i<(1<<n); ++i)
{
ll now=0,op=1;
for(int j=0; j<n; ++j)
{
if((i&(1<<j)))
{
now+=(f[j]+1ll);
if(now>b)break;
op^=1;
}
}
if(now>b)continue;
if(op)ans=(ans+(C(b-now+n,n)-C(a-now+n-1,n)+mod)%mod)%mod;
else ans=(ans-(C(b-now+n,n)-C(a-now+n-1,n)+mod)%mod+mod)%mod;
}
cout<<ans<<'\n';
}
return 0;
}