[BZOJ] 1042: [HAOI2008]硬币购物
每种硬币用完全背包算出,直接容斥
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define P(i) (c[i] * (d[i] + 1)) using namespace std; const int MAXN=100005; int c[5],d[5],s; int cnt; long long f[MAXN],ans; int main(){ for(int i = 1; i <= 4; i++) cin>>c[i]; cin >> cnt; for(int i = 1; i <= cnt; i++) { for(int j = 1; j <= 4; j++) cin>>d[j]; cin>>s; memset(f,0,sizeof(f)); f[0] = 1; for(int k = 1; k <= 4; ++k) for(int j = c[k]; j <= s; j++) f[j] += f[j - c[k]]; ans = f[s]; for(int k = 1; k <= 4; ++k) if(s - P(k) >= 0) ans -= f[s - P(k)]; if(s - P(1) - P(2) >= 0) ans += f[s - P(1) - P(2)]; if(s - P(2) - P(3) >= 0) ans += f[s - P(2) - P(3)]; if(s - P(3) - P(4) >= 0) ans += f[s - P(3) - P(4)]; if(s - P(2) - P(4) >= 0) ans += f[s - P(2) - P(4)]; if(s - P(1) - P(3) >= 0) ans += f[s - P(1) - P(3)]; if(s - P(1) - P(4) >= 0) ans += f[s - P(1) - P(4)]; if(s - P(1) - P(2) - P(3) >= 0) ans -= f[s - P(1) - P(2) - P(3)]; if(s - P(2) - P(3) - P(4) >= 0) ans -= f[s - P(2) - P(3) - P(4)]; if(s - P(1) - P(3) - P(4) >= 0) ans -= f[s - P(1) - P(3) - P(4)]; if(s - P(1) - P(2) - P(4) >= 0) ans -= f[s - P(1) - P(2) - P(4)]; if(s - P(1) - P(2) - P(3) - P(4) >= 0) ans += f[s - P(1) - P(2) - P(3) - P(4)]; printf("%lld\n",ans); } return 0; }
本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9383939.html