Light oj 1233

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1233

题目就不说明了。

背包的二进制优化,比如10可以表示为1 2 4 3,而这些数能表示1 ~ 10的任意的数。然后类似01背包就好了。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <ctime>
 8 #include <queue>
 9 #include <list>
10 #include <set>
11 #include <map>
12 using namespace std;
13 #define INF 0x3f3f3f3f
14 typedef long long LL;
15 const int N = 1e5 + 5;
16 int dp[N];
17 int val[105], c[105];
18 
19 int main()
20 {
21     int t, n, m;
22     scanf("%d", &t);
23     for(int ca = 1; ca <= t; ++ca) {
24         scanf("%d %d", &n, &m);
25         for(int i = 1; i <= n; ++i) {
26             scanf("%d", val + i);
27         }
28         for(int i = 1; i <= n; ++i) {
29             scanf("%d", c + i);
30         }
31         memset(dp, 0, sizeof(dp));
32         dp[0] = 1;
33         for(int i = 1; i <= n; ++i) {
34             for(int k = 1; k <= c[i]; k <<= 1) {
35                 for(int j = m; j >= k*val[i]; --j) {
36                     dp[j] |= dp[j - k*val[i]];
37                 }
38                 c[i] -= k;
39             }
40             if(c[i]) {
41                 for(int j = m; j >= c[i]*val[i]; --j) {
42                     dp[j] |= dp[j - c[i]*val[i]];
43                 }
44             }
45         }
46         int ans = 0;
47         for(int i = 1; i <= m; ++i) {
48             ans += dp[i];
49         }
50         printf("Case %d: %d
", ca, ans);
51     }
52     return 0;
53 }
原文地址:https://www.cnblogs.com/Recoder/p/5965081.html