链接:https://vjudge.net/problem/HDU-2844#author=CCOA
题意:
给定几种不同面额的硬币若干枚,需要求的用这些硬币可以组成多少种范围在1~m的不同面额的组合。
思路:
多重背包,二进制优化。
代码:
#include <iostream> #include <memory.h> #include <vector> #include <map> #include <algorithm> #include <cstdio> #include <math.h> using namespace std; typedef long long LL; const int MAXN = 1e2 + 10; const int MAXM = 1e5 + 10; const int INF = 1e9; int dp[MAXM]; int a[MAXN], b[MAXN]; int main() { int n, m; while (scanf("%d %d", &n, &m), n|m) { memset(dp, 0, sizeof(dp)); for (int i = 1;i <= n;i++) scanf("%d", &a[i]); for (int i = 1;i <= n;i++) scanf("%d", &b[i]); for (int i = 1;i <= n;i++) { int k = 1; int v; while (k <= b[i]) { v = k * a[i]; b[i] -= k; for (int j = m;j >= v;j--) dp[j] = max(dp[j], dp[j - v] + v); k = k << 1; } if (b[i] > 0) { k = b[i]; v = k * a[i]; for (int j = m;j >= v;j--) dp[j] = max(dp[j], dp[j - v] + v); } } int res = 0; for (int i = 1;i <= m;i++) if (dp[i] == i) res++; printf("%d ", res); } return 0; }