【题意分析】
有q个询问,每次询问求一个只有四个物品的背包方案数。
【解题思路】
先计算出所有面值硬币的无限背包方案数。
考虑容斥,每个限制表示选取大于di个面值ci的硬币,总方案数=0限制方案数-1限制方案数+2限制方案数-3限制方案数+4限制方案数。
总复杂度O(max(s)+24)。
【参考代码】
1 #pragma GCC optimize(2) 2 #include <cstdio> 3 #include <cstring> 4 #define REP(i,low,high) for(register int i=(low);i<=(high);i++) 5 #define for_range(i,size) for(register int i=0;i<(size);i++) 6 using namespace std; 7 int T,c[100010],d[100010]; unsigned long long f[100010]; 8 unsigned long long query(const short &now,const int &tar,const short &sig) 9 { 10 return tar<0?0ull:(now>3?sig*f[tar]:query(now+1,tar,sig)+query(now+1,tar-c[now]*(d[now]+1),-sig)); 11 } 12 int main() 13 { 14 memset(f,0,sizeof f),f[0]=1ull; for_range(i,4) {scanf("%d",c+i); REP(j,c[i],100000) f[j]+=f[j-c[i]];} 15 for(scanf("%d",&T);T--;) {int s; for_range(i,4) scanf("%d",d+i); scanf("%d",&s),printf("%llu\n",query(0,s,1));} 16 return 0; 17 }
We Secure, We Contain, We Protect.