HDU-2844:Coins(多重背包+二进制优化)
题意:给你n个种类的钱和对应的数量,同统计一下从1到m能够凑成的钱有多少个。
题解:C[i] = 1 + 2 + 4 + ··· + 2^k + a (0 <= a < 2^(k+1))。
#include <bits/stdc++.h> using namespace std; const double EPS = 1e-6; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; const int maxn = 1e5 + 10; int n, m; int a[maxn], c[maxn]; int dp[maxn]; int main() { while(scanf("%d%d", &n, &m) && (n || m)){ for(int i = 1; i <= n; i++) scanf("%d", &a[i]); for(int i = 1; i <= n; i++) scanf("%d", &c[i]); memset(dp, 0, sizeof(dp)); dp[0] = 1; for(int i = 1; i <= n; i++){ int num = c[i]; for(int k = 1; num > 0; k <<= 1){ int mul = min(k, num); for(int j = m; j >= a[i] * mul; j--){ if(dp[j - a[i] * mul])dp[j] = 1; } num -= mul; } } int ans = 0; for(int i = 1; i <= m; i++) if(dp[i]) ans++; printf("%d\n", ans); } return 0; }