计数的核心是双射。
解析
这也叫数位dp呗…
首先,这个题目的形式很容易令人想到硬币购物,考虑用容斥解决,暴力枚举强制超额的数的集合然后分别计算贡献。
然而,暴力dp计算贡献的复杂度是 O(n2)O(n^2)O(n2) 的。
考虑换一种统计的角度。
设 f(i,s)f(i,s)f(i,s) 表示填到第 i 位,可以随便填的数的状态为S的方案数。这里的随便填既包括一开始没有钦定过量,也包括一开始钦定了但已经过量的部分。
转移时,要么填一个本来就随便填的,要么把一个不能随便填的数直接填 ai+1a_i+1ai+1 个然后把其加入S。
不难发现这样的统计是不重不漏的。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define ldb long double
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
using namespace std;const int N=2e4+100;
const int inf=1e9;
const int mod=1e9+7;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}inline ll ksm(ll x,ll k){ll res(1);while(k){if(k&1) res=res*x%mod;x=x*x%mod;k>>=1;}return res;
}int n,m;
int mi[6],bit[35];
int a[5];
ll f[N][33];
inline int calc(int x){int res(0);while(x){if(x&1) ++res;x>>=1;}return res;
}
ll jc[N],ni[N];
void init(int n){jc[0]=1;for(int i=1;i<=n;i++) jc[i]=jc[i-1]*i%mod;ni[n]=ksm(jc[n],mod-2);for(int i=n-1;i>=0;i--) ni[i]=ni[i+1]*(i+1)%mod;return;
}
inline ll C(int n,int m){//if(n<m) debug("%d %d\n",n,m);return jc[n]*ni[m]%mod*ni[n-m]%mod;
}
ll calc(){memset(f,0,sizeof(f));for(int i=0;i<mi[5];i++) f[0][i]=(bit[i]&1)?1:mod-1;for(int i=0;i<n;i++){for(int s=0;s<mi[5];s++){(f[i+1][s]+=bit[s]*f[i][s])%=mod;for(int j=0;j<5;j++){if((s&mi[j])==0&&i+1>=a[j]+1){//assert((i+1)-(a[j]+1)>=0);(f[i+1][s|mi[j]]+=f[(i+1)-(a[j]+1)][s]*C(i,a[j]))%=mod;}}}//for(int s=0;s<mi[5];s++) printf("i=%d s=%d bit=%d f=%lld\n",i+1,s,bit[s],f[i+1][s]);} return f[n][mi[5]-1];
}
int clo;
void work(){ printf("Case #%d: ",++clo);n=read();for(int i=0;i<5;i++) a[i]=read();ll ans=calc();if(a[0]){a[0]--;n--;ans=(ans+mod-calc())%mod; }printf("%lld\n",ans);
}
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);#endifmi[0]=1;for(int i=1;i<=5;i++) mi[i]=mi[i-1]<<1;for(int i=1;i<mi[5];i++) bit[i]=bit[i-(i&-i)]+1;init(2e4);int T=read();while(T--) work();return 0;
}
/*
test in:http://acm.hdu.edu.cn/showproblem.php?pid=5519
*/