백준 8313번 Sweets
중국의 의문의 블로그에서 풀이를 보고 풀었다. 여기서 찾았다.
Anton, Dmytro, Borys이 각각 받을 사탕의 개수를
이라고 하자.
차를 이용해 변수 3개를 2개로 줄이는 아이디어가 인상깊었다.
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXC = 600000;
ll N, tree[4*MAXC];
void update(int x, ll v, int s = 0, int e = MAXC, int idx = 1)
{
if(e < x || x < s) return;
if(s == e) {
tree[idx] = min(tree[idx], v);
return;
}
int m = (s + e) / 2;
update(x, v, s, m, 2*idx);
update(x, v, m+1, e, 2*idx+1);
tree[idx] = min(tree[2*idx], tree[2*idx+1]);
}
ll query(int l, int r, int s = 0, int e = MAXC, int idx = 1)
{
if(e < l || r < s) return 1e18;
if(l <= s && e <= r) return tree[idx];
int m = (s + e) / 2;
return min(query(l, r, s, m, 2*idx), query(l, r, m+1, e, 2*idx+1));
}
void dfs(int idx, ll a, ll b, ll c, vector<ll>& A, vector<pair<ll, ll>>& out)
{
if(idx == A.size()) {
out.emplace_back(c - b, b - a);
return;
}
dfs(idx + 1, a + A[idx], b, c, A, out);
dfs(idx + 1, a, b + A[idx], c, A, out);
dfs(idx + 1, a, b, c + A[idx], A, out);
}
int main()
{
cin >> N;
vector<ll> A(N);
for(int i = 0; i < N; i++) cin >> A[i];
int m = N / 2;
vector<ll> front(A.begin(), A.begin() + m), back(A.begin() + m, A.end());
vector<pair<ll, ll>> front_out, back_out;
dfs(0, 0, 0, 0, front, front_out);
dfs(0, 0, 0, 0, back, back_out);
sort(front_out.begin(), front_out.end());
sort(back_out.begin(), back_out.end());
vector<ll> v;
v.reserve(back_out.size());
for(auto [a, b] : back_out) v.push_back(b);
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
fill(tree, tree + 4*MAXC, 1e18);
ll ans = 1e18;
int j = back_out.size() - 1;
for(int i = 0; i < front_out.size(); i++) {
while(j >= 0 && front_out[i].first + back_out[j].first >= 0) {
int idx = lower_bound(v.begin(), v.end(), back_out[j].second) - v.begin();
update(idx, back_out[j].first + back_out[j].second);
j--;
}
int idx = lower_bound(v.begin(), v.end(), -front_out[i].second) - v.begin();
ans = min(ans, front_out[i].first + front_out[i].second + query(idx, MAXC));
}
cout << ans;
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.