๐ ๋ฌธ์ ๋งํฌ
https://www.acmicpc.net/problem/1208
โธ ๋ฌธ์
N๊ฐ์ ์ ์๋ก ์ด๋ฃจ์ด์ง ์์ด์ด ์์ ๋, ํฌ๊ธฐ๊ฐ ์์์ธ ๋ถ๋ถ์์ด ์ค์์ ๊ทธ ์์ด์ ์์๋ฅผ ๋ค ๋ํ ๊ฐ์ด S๊ฐ ๋๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ตฌํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ์์ค.
โธ ์ ๋ ฅ
์ฒซ์งธ ์ค์ ์ ์์ ๊ฐ์๋ฅผ ๋ํ๋ด๋ N๊ณผ ์ ์ S๊ฐ ์ฃผ์ด์ง๋ค. (1 ≤ N ≤ 40, |S| ≤ 1,000,000) ๋์งธ ์ค์ N๊ฐ์ ์ ์๊ฐ ๋น ์นธ์ ์ฌ์ด์ ๋๊ณ ์ฃผ์ด์ง๋ค. ์ฃผ์ด์ง๋ ์ ์์ ์ ๋๊ฐ์ 100,000์ ๋์ง ์๋๋ค.
โธ ์ถ๋ ฅ
์ฒซ์งธ ์ค์ ํฉ์ด S๊ฐ ๋๋ ๋ถ๋ถ์์ด์ ๊ฐ์๋ฅผ ์ถ๋ ฅํ๋ค.
๐ ๋ฌธ์ ์ ๋ณด
- ๐ฅ ๋ฌธ์ ๋ ๋ฒจ : ๊ณจ๋ 1
- ๐ ๋ฌธ์ ์ ํ : ์ด๋ถ ํ์, ์ค๊ฐ์์ ๋ง๋๊ธฐ
- ๐ฌ ํ์ด ์ธ์ด : JAVA
๐ค ๋ฌธ์ ํ์ด
N๊ฐ์ ์ ์๊ฐ ์ฃผ์ด์ก์ ๋, ํฌ๊ธฐ๊ฐ ์์์ธ ๋ถ๋ถ์์ด ์ค์์ ์์ ํฉ์ด S๊ฐ ๋๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ตฌํ๋ ๋ฌธ์ ์ด๋ค.
๋จ, N์ ์ต๋ 40์ด๋ฏ๋ก ๋จ์ํ ๋ถ๋ถ์งํฉ ํ์์ผ๋ก๋ ์๊ฐ ์ด๊ณผ ๊ฐ๋ฅ์ฑ์ด ํฌ๋ค.
๊ทธ๋ฌ๋ฏ๋ก Boj_1450 ๋ ์๋ฌธ์ ์๋ ํ์ฉํ๋ ์ค๊ฐ์์ ๋ง๋๊ธฐ(Meet in the middle) ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ํด๊ฒฐํ ์ ์๋ค.
1๏ธโฃ ๋ฐฐ์ด ๋๋๊ธฐ
๋ฐฐ์ด์ ๋ฐ์ผ๋ก ๋๋๊ณ , ๊ฐ ์ ๋ฐ์์ ๊ฐ๋ฅํ ๋ถ๋ถ์งํฉ์ ํฉ์ ์ ๋ถ ๋ฆฌ์คํธ์ ์ ์ฅํ๋ค.
์ด๋, ์ฌ๊ท ํจ์๋ฅผ ์ด์ฉํด ๋ชจ๋ ์กฐํฉ์ ํ์ํ๋ค.
private static void comb(int start, int end, ArrayList<Integer> list, int sum) {
if (start == end) {
list.add(sum);
return;
}
comb(start+1, end, list, sum+arr[start]); // ํ์ฌ ์์ ํฌํจ
comb(start+1, end, list, sum); // ํ์ฌ ์์ ๋ฏธํฌํจ
}
- start๋ถํฐ end ์ ๊น์ง ๋ชจ๋ ๋ถ๋ถ์งํฉ์ ํฉ์ ๊ตฌํด list์ ์ ์ฅํ๋ค.
- ์ด๋ ๊ฒ ํ๋ฉด ์ผ์ชฝ ์ ๋ฐ(left)์ ์ค๋ฅธ์ชฝ ์ ๋ฐ(right)์ ๋ชจ๋ ๋ถ๋ถ์งํฉ์ ํฉ์ ๊ตฌํ ์ ์๋ค.
2๏ธโฃ ๋ ๋ฆฌ์คํธ์ ์กฐํฉ์ผ๋ก S ๋ง๋ค๊ธฐ
์ผ์ชฝ ๋ฆฌ์คํธ์ ๊ฐ ์์ x์ ๋ํด, ์ค๋ฅธ์ชฝ ๋ฆฌ์คํธ์์ S-x๊ฐ ๋ช ๋ฒ ๋ฑ์ฅํ๋์ง๋ฅผ ์ฐพ์ ์นด์ดํธํ๋ค.
์ด๋ฅผ ํจ์จ์ ์ผ๋ก ํ๊ธฐ ์ํด ์ค๋ฅธ์ชฝ ๋ฆฌ์คํธ๋ฅผ ์ ๋ ฌํ ๋ค, ์ด์ง ํ์์ ์ฌ์ฉํ๋ค.
3๏ธโฃ ์ด์ง ํ์, lower_bound์ upper_bound
private static int upperBound(ArrayList<Integer> list, int target) {
int left = 0;
int right = list.size();
while (left < right) {
int mid = (left+right)/2;
if (list.get(mid) <= target) left = mid+1;
else right = mid;
}
return right;
}
private static int lowerBound(ArrayList<Integer> list, int target) {
int left = 0;
int right = list.size();
while (left < right) {
int mid = (left+right)/2;
if (list.get(mid) >= target) right = mid;
else left = mid+1;
}
return right;
}
- lowerBound : target ์ด์์ด ์ฒ์ ๋์ค๋ ์์น
- upperBound : target ์ด๊ณผ๊ฐ ์ฒ์ ๋์ค๋ ์์น
- ์ ๋ ฌ๋ ๋ฆฌ์คํธ์ผ ๋, upperBound - lowerBound๊ฐ target์ ๋ฑ์ฅ ํ์๊ฐ ๋๋ค.
โ ๏ธ ๊ณต์งํฉ ์ฒ๋ฆฌ
๊ฐ ๋ฆฌ์คํธ (left, right)์๋ ๊ณต์งํฉ ํฉ(0)์ด ํฌํจ๋๋ค.
๋ฌธ์ ์์ ํฌ๊ธฐ๊ฐ ์์์ธ ๋ถ๋ถ์์ด๋ง ์ธ์ผ ํ๋ฏ๋ก, S==0์ธ ๊ฒฝ์ฐ์๋ ๋ ๊ณต์งํฉ์ ๋์์ ์ ํํ๋ ๊ฒฝ์ฐ๋ฅผ ๋นผ์ฃผ์ด์ผ ํ๋ค.
์ ํ์ด์ ์ฝ๋๋ฅผ ๋ฐํ์ผ๋ก ์ ์ฒด์ ์ธ ์ฝ๋๋ฅผ ์์ฑํด ๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
โ ์ฝ๋
๋ฉ๋ชจ๋ฆฌ : 80096KB
์๊ฐ : 1268ms
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;
public class Main {
static int[] arr;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int s = Integer.parseInt(st.nextToken());
arr = new int[n];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
ArrayList<Integer> left = new ArrayList<>();
ArrayList<Integer> right = new ArrayList<>();
comb(0, n/2, left, 0);
comb(n/2, n, right, 0);
Collections.sort(right);
long ans = 0;
for (int i = 0; i < left.size(); i++) {
int target = s-left.get(i);
int upper = upperBound(right, target);
int lower = lowerBound(right, target);
ans += upper - lower;
}
System.out.println(s == 0 ? ans-1 : ans);
br.close();
}
private static int upperBound(ArrayList<Integer> list, int target) {
int left = 0;
int right = list.size();
while (left < right) {
int mid = (left+right)/2;
if (list.get(mid) <= target) left = mid+1;
else right = mid;
}
return right;
}
private static int lowerBound(ArrayList<Integer> list, int target) {
int left = 0;
int right = list.size();
while (left < right) {
int mid = (left+right)/2;
if (list.get(mid) >= target) right = mid;
else left = mid+1;
}
return right;
}
private static void comb(int start, int end, ArrayList<Integer> list, int sum) {
if (start == end) {
list.add(sum);
return;
}
comb(start+1, end, list, sum+arr[start]);
comb(start+1, end, list, sum);
}
}
'Algorithm > BOJ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Boj_10972] ๋ค์ ์์ด (0) | 2025.08.20 |
---|---|
[Boj_1450] ๋ ์๋ฌธ์ (3) | 2025.08.07 |
[Boj_1561] ๋์ด ๊ณต์ (4) | 2025.08.05 |
[Boj_1194] ์์ด์คํฌ๋ฆผ ๋๋ ์งํธ (3) | 2025.08.05 |
[Boj_1194] ๋ฌ์ด ์ฐจ์ค๋ฅธ๋ค, ๊ฐ์. (0) | 2025.07.25 |