# AHU-743 多重部分和问题 【多重背包变种】

Description

Input

Output

Sample Input
2
3
3 5 8
3 2 2
17
2
1 2
1 1
4

Sample Output
Yes
No

题解：15年省赛的一道题，题目没啥难度，看下数据范围多重背包可以跑，只需要看某个状态i是否可以达到用bool数组就行，二进制优化0ms。代码：
 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define INF 0x3f3f3f3f
4 #define M(a, b) memset(a, b, sizeof(a))
5 const int N = 105;
6 int a[N], num[N];
7 bool f[100005];
8
9 int main() {
10     int T, n, k;
11     scanf("%d", &T);
12     while (T--) {
13         scanf("%d", &n);
14         for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
15         for (int i = 1; i <= n; ++i) scanf("%d", &num[i]);
16         scanf("%d", &k);
17         M(f, 0); f[0] = 1;
18         for (int i = 1; i <= n; ++i) {
19             int sum = num[i] * a[i];
20             if (sum >= k) {
21                 for (int j = a[i]; j <= k; ++j)
22                     if (f[j-a[i]]) f[j] = 1;
23             }
24             else {
25                 int m = num[i];
26                 for (int j = 1; j <= m; m-=j, j <<= 1) {
27                     int y = j*a[i];
28                     for (int x = k; x >= y; --x)
29                         if (f[x-y]) f[x] = 1;
30                 }
31                 int y = m*a[i];
32                 for (int x = k; x >= y; --x)
33                     if (f[x-y]) f[x] = 1;
34             }
35         }
36         if (f[k]) printf("Yes\n");
37         else printf("No\n");
38     }
39
40     return 0;
41 }

posted @ 2017-05-02 13:41  Robin!  阅读(...)  评论(...编辑  收藏