容斥+背包。
先做完全背包,然后就去掉用的硬币大于限量的,用容斥原理去下重就行了。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N=100005; int c[5],T;long long f[N];int d[5],s; int main() { for(int i=1;i<=4;i++) scanf("%d",&c[i]); scanf("%d",&T); f[0]=1; for(int j=1;j<=4;j++) for(int i=c[j];i<=N-5;i++) f[i]+=f[i-c[j]]; while(T--) { for(int i=1;i<=4;i++) scanf("%d",&d[i]); scanf("%d",&s); long long ans=0; for(int i=0;i<=15;i++) { long long tp=s;short rc=1; for(int j=0;j<4;j++) if(i&(1<<j)) tp-=c[j+1]*(d[j+1]+1),rc=-rc; if(tp<0) continue; ans+=f[tp]*rc; } printf("%lld ",ans); } return 0; }