先用递推算出硬币无限的所有方案数,然后,因为一个硬币超限的最小个数是d[i]+1,能使硬币超限的最小钱数是c[i](d[i]+1),对于一个硬币超限的所有情况就是f[sum-c[i](d[i]+1)],然而4个硬币超限的情况并是有重叠关系,这就用到容斥原理的关系,奇数个就-,偶数个就加
#include<cstdio>
#include<cstring>
#define maxn 100010
int m,t,c[5],d[5],qian;
long long f[maxn],ans;
void dt()
{
f[0]=1;
for(int i=1;i<=4;i++)
for(int j=c[i];j<=100000;j++)
f[j]+=f[j-c[i]];
}
void prework()
{
for(int i=1;i<=4;i++)
scanf("%d",&d[i]);
scanf("%d",&qian);
}
void dfs(int x,int k,int sum)
{
if(sum<0)
return;
if(x==5)
{
if(k%2)
ans-=f[sum];
else
ans+=f[sum];
return;
}
dfs(x+1,k+1,sum-(d[x]+1)*c[x]);
dfs(x+1,k,sum);
}
void mainwork()
{
ans=0;
dfs(1,0,qian);
}
void print()
{
printf("%lld\n",ans);
}
int main()
{
for(int i=1;i<=4;i++)
scanf("%d",&c[i]);
scanf("%d",&t);
dt();
for(int i=1;i<=t;i++)
{
prework();
mainwork();
print();
}
return 0;
}