Luogu P1450 [HAOI2008]硬币购物

时间:2022-12-19 22:14:40

题目

一个很自然的想法是容斥。

假如只有一种硬币,那么答案就是没有限制的情况下买\(s\)的方案数减去强制用了\(d+1\)枚情况下买\(s\)的方案数即没有限制的情况下买\(s-c(d+1)\)的方案数。

现在是多种硬币,所以要加个容斥。

那么我们需要预处理一下没有限制的情况下买\(i\)的方案数。

#include<cstdio>
#define ll long long
const int N=100001;
int c[5],d[5];ll f[N];
int read(){int x;scanf("%d",&x);return x;}
int main()
{
int i,j,s,t,flg;ll ans;f[0]=1;
for(i=1;i<=4;++i) c[i]=read();
for(i=1;i<=4;++i) for(j=c[i];j<=100000;++j) f[j]+=f[j-c[i]];
for(int T=read();T;--T)
{
ans=0;
for(i=1;i<=4;++i) d[i]=read();
s=read();
for(i=0;i<=15;++i)
{
t=s,flg=0;
for(j=0;j<4;++j) if(i&1<<j) t-=c[j+1]*(d[j+1]+1),flg^=1;
if(t<0) continue;
ans+=(flg? -1:1)*f[t];
}
printf("%lld\n",ans);
}
}