[BZOJ1042][HAOI2008]硬币购物[容斥原理+背包]

这个比较详细

显然即可请别发题解

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll f[1000005], n;
int T, c[4], d[4], s;
 
int main(void){
    for (int i = 0; i < 4; ++i) cin >> c[i];
    f[0] = 1;
    for (int i = 0; i < 4; ++i) for (int j = c[i]; j <= 1000000; ++j) f[j] += f[j - c[i]];
    cin >> T;
    while (T--) {
        for (int i = 0; i < 4; ++i) scanf("%d", d+i); scanf("%d", &s);
        ll ans = 0;
        for (int i = 0; i < 16; ++i) {
            int cnt = 0, S = i, tmp = s;
            while (S) {
                int p = __builtin_ctz(S);
                tmp -= (d[p] + 1) * c[p];
                S -= 1 << p;
                ++cnt;
            }
            if (tmp >= 0) ans += ((cnt & 1) ? -1 : 1) * f[tmp];
        }
        cout << ans << endl;
    }
    return 0;
}
posted @ 2019-01-03 11:44  QvvQ  阅读(...)  评论(... 编辑 收藏