【POJ1742】Coins
关于多重背包的一道题。
首先看数据便知道朴素的多重背包无法通过,所以我们采用二进制拆分进行优化,(二进制优化点这里),这样就能顺利通过本题了。
这道题只是判断可行性,所以“价值”这一状态并没有什么用。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 bool dp[100010]; 7 int v[110]; 8 int save[10000]; 9 int main() { 10 int n, m; 11 while (scanf("%d%d", &n, &m) != EOF&&n&&m) { 12 int i, j, k, len = 0; 13 for (i = 1; i <= m; i++) 14 dp[i] = false; 15 for (i = 0; i < n; i++) 16 scanf("%d", &v[i]); 17 int num; 18 for (i = 0; i < n; i++) { 19 scanf("%d", &num); 20 int q = 1; 21 while (q < num) { 22 save[len++]=q*v[i]; 23 num -= q; 24 q *= 2; 25 } 26 save[len++] = num*v[i]; 27 } 28 dp[0] = true; 29 for (i = 0; i < len; i++) { 30 for (j = m; j >= save[i]; j--) { 31 if (!dp[j]) 32 dp[j] = dp[j-save[i]]; 33 } 34 } 35 int cot = 0; 36 for (i = 1; i <= m; i++) { 37 if (dp[i]) 38 cot++; 39 } 40 printf("%d\n", cot); 41 } 42 return 0; 43 }