๐ Link : https://www.acmicpc.net/problem/19942
๐ก ์ ๊ทผ ๋ฐฉ๋ฒ
1. ๋ฌธ์ ์ดํด & ์ ํฉํ ์๊ณ ๋ฆฌ์ฆ ์ฐพ๊ธฐ
์์ฌ๋ฃ์ ๊ฐ๊ฐ์ ์กฐํฉ์ ๋ฐ๋ผ์ ์ํ๋ ์์์๋ฅผ ๋๋ ์ต์๋น์ฉ์ ๊ตฌํด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ฐฑํธ๋ ํน์ด ์ ํฉํด ๋ณด์ธ๋ค. ํ์ง๋ง ์ด์ ์ ํ์ดํ๋ ๋ฌธ์ ์ ๋ค๋ฅด๊ฒ ๋ฐฑํธ๋ ํน์ด ํ์ถํ ํฌ์ธํธ๋ฅผ depth๊ฐ ์๋ ๋ค๋ฅธ ๋ถ๋ถ์ ์ ํด์ผ ํ๋ค. ํญ์ depth๋ก๋ง ํ์ดํ๋ค๊ฐ ์กฐ๊ธ ํผ๋์ค๋ฌ์ ๋ค. ์ฐ์ ๋ฐฑํธ๋ ํน์ ํ์ ์ด๋ ์ ๋ ์์ฑํด ๋๊ณ ์ด๋ค ๊ฒ์ ๊ตฌํด์ผ ํ ์ง ์์ฑํด ๋ดค๋ค.
- ์์์๋ฅผ ๋๋ ์์ฌ๋ฃ์ ์กฐํฉ์ด 1,2,5 = ๋น์ฉ 30 / 1,3,6,7 = ๋น์ฉ 10 ์ด๋ ๊ฒ ๋์ฌ ๊ฒฝ์ฐ 1,3,6,7์ ์ถ๋ ฅํด์ผ ํ๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ์กฐํฉ์ ์๋ฅผ ํ์ํ๋ ์์ด ํ์ํ๋ค.
- ์ต์ ๋น์ฉ์ด ๊ฐฑ์ ๋ ๊ฒฝ์ฐ ์ด์ ์์ฌ๋ฃ์ ๋ฒํธ๋ฅผ ์ ๊ฑฐ ํ ์๋ก์ด ์กฐํฉ์ ์์ฌ๋ฃ ๋ฒํธ๋ฅผ ๋ฃ์ด์ผ ํ๋ค
์์งํ ๋ค๋ฅธ ๋ถ๋ถ์ ์ ๊ทผํ๊ธฐ ์ฌ์ ๋ค. ํ์ง๋ง ๋ชจ๋ ์กฐํฉ์ ์ฐพ์๋ณด๋ ๋ฐฉ๋ฒ์ ๋ํด์ ๊ตฌํ์ ํ๊ธฐ ์ด๋ ค์ ๊ตฌ๊ธ๋ง์ ํด์ ์ฐพ์๋ดค๋ค.
์ฐธ๊ณ ๋ธ๋ก๊ทธ : https://dang2dangdang2.tistory.com/192
์ ๋ธ๋ก๊ทธ์์ ์ด๋ ๊ฒ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์๋ค ํ์ง๋ง ์๋ฌด๋ฆฌ ๋๋ฒ๊ทธ๋ฅผ ๋๋ ค๋ด๋ ๋ด ๋จธ๋ฆฌ๋ก๋ ์ดํด๊ฐ ๋ถ๊ฐ๋ฅํด ๋ณด์๋ค. ์ ์ ๋ ๊ฒ ์ฌ์ฉ์ ํ๋์ง ์๋ฟ์ง ์์๋ค. ๊ทธ๋์ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ์ ๊ทผํด๋ณด๋ ค๊ณ ํ๋ค.
//ํ๊ฐ ๊ณ ๋ฅด๋ ๊ฒ ๋ถํฐ N๊ฐ ๋ชจ๋ ๋ค ๊ณ ๋ฅด๋ ๊ฒ ๊น์ง ๊ณ ๋ ค
for(int i=1;i<=N;i++){
isSelected = new int[N];
dfs(0,i,1);
}
static void dfs(int cnt,int choiceNum,int start){...}
2. ๋ฌธ์ ํ์ด
์ด์ ๋ฐฑํธ๋ ํน ๋ฌธ์ ๋ฅผ ํ์๋ ์ํ์ ์ธ : https://www.acmicpc.net/problem/17610 ๋ฌธ์ ๋ฅผ ๋ ์ฌ๋ ค์ ํ์ฉํ๊ธฐ๋ก ํ๋ค ์๋ ๋ฌธ์ ์ ๊ฒฝ์ฐ์ ๋ฐ๋ผ ๊ฐ๊ฐ dfs๋ฅผ ๋๋ฆฌ๋ฉด ๋๋ค.
๋ฌธ์ ๋ฅผ ๋ ์ฌ๋ ค์ ํ์ฉํ๊ธฐ๋ก ํ๋ค ์ ๋ฌธ์ ์ ๊ฒฝ์ฐ์ ๋ฐ๋ผ ๊ฐ๊ฐ dfs๋ฅผ ๋๋ฆฌ๋ฉด ๋๋ค.
private static void dfs(int weight, int depth) {
if (depth == N) {
isTrue[weight] = true;
return;
}
// ํ์ฌ ๋ฌด๊ฒ(weight)์ ๋ค์ ์ถ์ ๋ฌด๊ฒ(arr[depth])๋ฅผ ๋ํ ๊ฒฝ์ฐ
dfs(weight + arr[depth], depth + 1);
// ํ์ฌ ๋ฌด๊ฒ(weight)๋ฅผ ๊ทธ๋๋ก ์ ์งํ๋ ๊ฒฝ์ฐ
dfs(weight, depth + 1);
// ํ์ฌ ๋ฌด๊ฒ(weight)์์ ๋ค์ ์ถ์ ๋ฌด๊ฒ(arr[depth])๋ฅผ ๋บ ๊ฒฝ์ฐ
dfs(Math.abs(weight - arr[depth]), depth + 1);
}
์ด๋ ๊ฒ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ์ฌ๊ท๋ฅผ ๋๋ ค์ฃผ๋ฉด์ ์ฃผ์ด์ง ์ถ๋ค๋ก ์ธก์ ํ ์ ์๋ ๋ชจ๋ ๋ฌด๊ฒ๋ฅผ ์ฐพ์๋ผ ์ ์์๋ค. ๊ทธ๋ ๋ค๋ฉด ์ ๋ฐฉ์์ ์ ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ ๋ญ๊น?
- ํ์ฌ ์์ฌ๋ฃ๋ฅผ ํฌํจํ๋ ๊ฒฝ์ฐ
- ํ์ฌ ์์ฌ๋ฃ๋ฅผ ํฌํจํ์ง ์๋ ๊ฒฝ์ฐ
์ด๋ ๊ฒ ๋ ๊ฐ์ง์ ๊ฒฝ์ฐ๋ฅผ ์ค์ ํด์ ์ฌ๊ท๋ฅผ ๋๋ฆด ์๊ฐ ์๋ค. ์ต์๋น์ฉ์ ๊ตฌํ ์ ์๊ฒ ๋์๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๋ ์ด๋ค ์์ฌ๋ฃ๊ฐ ํฌํจ๋๋์ง ์์ฌ๋ฃ์ ๋ฒํธ๋ฅผ ๋ด์ List๊ฐ ํ์ํ๊ณ ์ด๋ค ์์ฌ๋ฃ๋ฅผ ๋ด์ ๊ฒ์ธ์ง ๊ท์น์ด ํ์ํ๋ค.
private static void backtracking() {
if(ํ์ถ์กฐ๊ฑด : ์ํ๋ ์์์๋ฅผ ๋ชจ๋ ๋๊ฒผ์ ๊ฒฝ์ฐ) {
์ต์ ๋น์ฉ ๊ฐฑ์ ();
return;
}
ํ์ถ์กฐ๊ฑด์ ๋๋ฌ ํ๊ธฐ ์ํด ๊ฒฝ์ฐ์ ์๋ฅผ ์กฐํฉํด ์ฌ๊ท๋ฅผ ๋๋ฆฐ๋ค.
backtracking(ํ์ฌ ์์ฌ๋ฃ๋ฅผ ํฌํจํ๋ ๊ฒฝ์ฐ๋ฅผ ๋๊ฒจ์ค๋ค);
backtracking(ํ์ฌ ์์ฌ๋ฃ๋ฅผ ํฌํจํ์ง ์๋ ๊ฒฝ์ฐ๋ฅผ ๋๊ฒจ์ค๋ค);
}
์ฌ๊ธฐ์ ํ์ฌ ์์ฌ๋ฃ๋ฅผ ํฌํจํ๋ ๊ฒฝ์ฐ๋ฅผ ๋ฐฉ๋ฌธ์ฒดํฌ๋ฅผ ํ๊ณ ์์ฌ๋ฃ๋ฅผ ํฌํจํ์ง ์๋ ๊ฒฝ์ฐ๋ฅผ ๋๊ฒจ์ค ๊ฒฝ์ฐ ๋ฐฉ๋ฌธ์ฒดํฌ๋ฅผ ํด์ ํด์ ๋ณด๋ด์ฃผ๋ฉด ๋๋ค. ๋ํ ๋ต์ ์ถ๋ ฅํ ๊ฒฝ์ฐ ๋ฐฉ๋ฌธ์ฒดํฌ๊ฐ ๋์ด์๋ ์์ฌ๋ฃ๋ง ์ถ๋ ฅํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ๋ฐฉ๋ฌธ์ฒดํฌ๋ฅผ ํ๋ ์ฝ๋๋ฅผ ์ถ๊ฐํด ์ฃผ์.
private static void backtracking(int index, int ์์์ ..., int ๋์ ๋น์ฉ) {
if(ํ์ถ์กฐ๊ฑด : ์ํ๋ ์์์๋ฅผ ๋ชจ๋ ๋๊ฒผ์ ๊ฒฝ์ฐ) {
์ต์ ๋น์ฉ ๊ฐฑ์ (๋์ ๋น์ฉ);
return;
}
ํ์ถ์กฐ๊ฑด์ ๋๋ฌ ํ๊ธฐ ์ํด ๊ฒฝ์ฐ์ ์๋ฅผ ์กฐํฉํด ์ฌ๊ท๋ฅผ ๋๋ฆฐ๋ค.
isVisited[index] = true;
backtracking(index + 1, ์ด์ ์์์ + ํ์ฌ ์์์ ..., ์ด์ ๋์ ๋น์ฉ + ํ์ฌ ์์์ ๋น์ฉ);
isVisited[index] = false;
backtracking(index + 1, ์ด์ ์์์, ์ด์ ๋์ ๋น์ฉ);
}
์ด๋ ๊ฒ ๋ฐฉ๋ฌธ์ฒดํฌ๋ฅผ ํจ์ผ๋ก์จ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ์กฐํฉํ๋ ๋ฐฑํธ๋ ํน ํ์ ๊ตฌํํ์ผ๋ ์ ํด์ง ๊ฐ์ ๋ฃ์ด์ค ๊ตฌํ์ ํ๋ฉด ๋๊ฒ ๋ค. ์ด์ ๋ฌธ์ ์๋ ๋ค๋ฅด๊ฒ ๋ค๋ฅธ ์ ๊ทผ์ ํด์ผ ํด์ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ ธ๋ค. ๊ทธ๋๋ ์ด ํ์ด๊ฐ ์ดํด๊ฐ ๋ ์๋๋ ๊ฒ ๊ฐ๋ค.
๐ ํ์ด ์ฝ๋
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
static int N;
static int cost = Integer.MAX_VALUE;
static int[] target;
static boolean[] isVisited;
static Nutrient[] nutrients;
static List<Integer> answer = new ArrayList<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
nutrients = new Nutrient[N];
isVisited = new boolean[N];
target = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
for (int i = 0; i < N; i++) {
nutrients[i] = Nutrient.of(br.readLine());
}
backtracking(0, 0, 0, 0, 0, 0);
if (cost == Integer.MAX_VALUE) {
System.out.println(-1);
} else {
System.out.println(cost);
for (int a : answer) System.out.print(a + " ");
}
}
public static void backtracking(int index, int p, int f, int c, int v, int amount) {
if (p >= target[0] && f >= target[1] && c >= target[2] && v >= target[3]) {
check(amount);
return;
}
if (index >= N || amount >= cost) return;
isVisited[index] = true;
backtracking(index + 1, p + nutrients[index].protein, f + nutrients[index].fat,
c + nutrients[index].crab, v + nutrients[index].vitamin, amount + nutrients[index].price);
isVisited[index] = false;
backtracking(index + 1, p, f, c, v, amount);
}
private static void check(int amount) {
if (amount < cost) {
cost = amount;
answer.clear();
for (int i = 0; i < N; i++) {
if (isVisited[i]) answer.add(i + 1);
}
}
}
}
class Nutrient {
int protein, fat, crab, vitamin, price;
public Nutrient(int protein, int fat, int crab, int vitamin, int price) {
this.protein = protein;
this.fat = fat;
this.crab = crab;
this.vitamin = vitamin;
this.price = price;
}
public static Nutrient of(String food) {
int[] nutrient = Arrays.stream(food.split(" ")).mapToInt(Integer::parseInt).toArray();
return new Nutrient(nutrient[0], nutrient[1], nutrient[2], nutrient[3], nutrient[4]);
}
}
'Algorithm' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Java] 10971๋ฒ: ์ธํ์ ์ํ 2 (1) | 2024.04.10 |
---|---|
[Java] 15664๋ฒ: N๊ณผ M(10) (0) | 2024.03.31 |
[Java] 2023๋ฒ: ์ ๊ธฐํ ์์ (0) | 2024.03.02 |
[Java] 15686๋ฒ: ์นํจ ๋ฐฐ๋ฌ (1) | 2024.01.30 |