acwing-171. 送礼物

考点

  • DFS
  • 双向DFS

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn = 1 << 24;
ll n, w, m, ans, half, a[50], b[maxn];

void dfs1(int i, ll s) {
if (i == half) {
b[++m] = s;
return;
}
if (s + a[i] <= w) dfs1(i + 1, s + a[i]);
dfs1(i + 1, s);
}

void dfs2(int i, ll s) {
if (i == n + 1) {
int l = 1, r = m, p = w - s;
while (l <= r) {
int mid = (l + r) / 2;
if (b[mid] <= p)
l = mid + 1;
else
r = mid - 1;
}
ans = max(ans, s + b[r]);
return;
}
if (s + a[i] <= w) dfs2(i + 1, s + a[i]);
dfs2(i + 1, s);
}

int main() {
cin >> w >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
if (n == 1) {
cout << a[1];
return 0;
}
sort(a + 1, a + 1 + n, [](ll &a, ll &b) -> bool { return a > b; });
half = n / 2;
dfs1(1, 0);
sort(b + 1, b + 1 + m), m = unique(b + 1, b + 1 + m) - b - 1;
dfs2(half, 0);
cout << ans;
return 0;
}

思路

直接看图就好,注意几个坑点:

  • 记得开long long ,部分情况会溢出
  • 不要用upper_bound会超时,手写二分快一点
  • half等于n / 2即可,不要玄学剪枝