【题意】4种各有价值的硬币,t组数据,各给出一组硬币的数量,分别求满足给定价值的硬币方案数。
【解题】
读完题第一反应:摆花? 尝试写了个搜索,无果。苦思难解,看了题解发现要用完全背包预处理,还有神奇的容斥。emmmmm涨了一波见识
bj加减符号这个处理还是蛮有意思的 容斥风格; and 我还是想摆花嘤
#include <bits/stdc++.h> #define sc(x) scanf("%lld", &x) #define fr(i, n) for (register int i = 1; i <= n; i++) #define int long long const int N = 100050; int t, d[5], c[5], f[N], ans, s; void dfs(int x, int k, int bj) { //定义和摆花差不多,不过k这里表示还需要的金额数(倒着dp),bj用来记录加还是减(容斥 if (k < 0) return; if (x > 4) { ans += f[k] * bj; return; } //容斥容斥容斥 dfs(x + 1, k, bj); dfs(x + 1, k - (d[x] + 1) * c[x], -bj); } signed main() { fr(i, 4) { std::cin >> c[i]; } std::cin >> t; f[0] = 1; fr(i, 4) for (int j = c[i]; j <= 100001; j++) f[j] += f[j - c[i]]; while (t--) { ans = 0; fr(i, 4) { std::cin >> d[i]; } std::cin >> s; dfs(1, s, 1); printf("%lld\n", ans); } return 0; }