容斥原理
奇加偶减
A ∪ B ∪ C = A + B + C − A ∩ B − A ∩ C − B ∩ C + A ∩ B ∩ C A∪B∪C=A+B+C-A∩B-A∩C-B∩C+A∩B∩C A∪B∪C=A+B+C−A∩B−A∩C−B∩C+A∩B∩C
枚举:采用二进制(全排列)
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+5;
const int mod=1e9+7;
const int inf=1e18;
int c[5],d[5],n,s,f[maxn];
// 完全背包
void pack(){
f[0]=1;
for(int i=1;i<=4;i++){
for(int j=c[i];j<=1e5;j++){
f[j]+=f[j-c[i]];
}
}
}
// ans=f[s]-A∪B∪C∪D
// A=f[s-c[i]*(d[i]+1)]
// A∩B=f[s-(a+b)]
int sol(){
int tmp=0; // 计算并
for(int i=1;i<=15;i++){ // 枚举所有情况(二进制)
int now=0,num=0;
for(int j=0;j<4;j++){
int dig=(i&(1<<j));
if(dig){
now+=c[j+1]*(d[j+1]+1);
num++;
}
}
if(now>s) continue;
// 奇加偶减
if(num%2) tmp+=f[s-now];
else tmp-=f[s-now];
}
return f[s]-tmp;
}
signed main()
{
for(int i=1;i<=4;i++) scanf("%lld",&c[i]);
pack();
cin>>n;
while(n--){
for(int i=1;i<=4;i++) scanf("%lld",&d[i]);
scanf("%lld",&s);
printf("%lld\n",sol());
}
return 0;
}