# bzoj 1042 [HAOI2008]硬币购物 容斥

### 解法

$f_i$表示所有物品都无限取的时候的方案数

### 代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
template <typename node> void chkmax(node &x, node y) {x = max(x, y);}
template <typename node> void chkmin(node &x, node y) {x = min(x, y);}
template <typename node> void read(node &x) {
x = 0; int f = 1; char c = getchar();
while (!isdigit(c)) {if (c == '-') f = -1; c = getchar();}
while (isdigit(c)) x = x * 10 + c - '0', c = getchar(); x *= f;
}
int c[4], d[4], f[100010];
main() {
for (int i = 0; i < 4; i++) read(c[i]); f[0] = 1;
for (int i = 0; i < 4; i++)
for (int j = c[i]; j <= 1e5; j++)
f[j] += f[j - c[i]];
while (T--) {
for (int i = 0; i < 4; i++) read(d[i]);
int s; read(s); int ans = 0;
for (int i = 0; i <= 15; i++) {
int now = s, k = 1;
for (int j = 0; j < 4; j++)
if ((i >> j) & 1) now -= c[j] * (d[j] + 1), k ^= 1;
if (now < 0) continue;
if (k) ans += f[now]; else ans -= f[now];
}
cout << ans << "\n";
}
return 0;
}


posted @ 2018-08-14 22:13  谜のNOIP  阅读(...)  评论(...编辑  收藏