๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Algorithm

[Java] 19942๋ฒˆ: ๋‹ค์ด์–ดํŠธ

๐ŸŒŽ Link : https://www.acmicpc.net/problem/19942

 

19942๋ฒˆ: ๋‹ค์ด์–ดํŠธ

์‹์žฌ๋ฃŒ N๊ฐœ ์ค‘์—์„œ ๋ช‡ ๊ฐœ๋ฅผ ์„ ํƒํ•ด์„œ ์ด๋“ค์˜ ์˜์–‘๋ถ„(๋‹จ๋ฐฑ์งˆ, ํƒ„์ˆ˜ํ™”๋ฌผ, ์ง€๋ฐฉ, ๋น„ํƒ€๋ฏผ)์ด ์ผ์ • ์ด์ƒ์ด ๋˜์–ด์•ผ ํ•œ๋‹ค. ์•„๋ž˜ ํ‘œ์— ์ œ์‹œ๋œ 6๊ฐ€์ง€์˜ ์‹์žฌ๋ฃŒ ์ค‘์—์„œ ๋ช‡ ๊ฐœ๋ฅผ ์„ ํƒํ•ด์„œ ์ด๋“ค์˜ ์˜์–‘๋ถ„์˜ ๊ฐ

www.acmicpc.net


๐Ÿ’ก ์ ‘๊ทผ ๋ฐฉ๋ฒ•

1. ๋ฌธ์ œ ์ดํ•ด & ์ ํ•ฉํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ฐพ๊ธฐ

์‹์žฌ๋ฃŒ์˜ ๊ฐ๊ฐ์˜ ์กฐํ•ฉ์— ๋”ฐ๋ผ์„œ ์›ํ•˜๋Š” ์˜์–‘์†Œ๋ฅผ ๋„˜๋Š” ์ตœ์†Œ๋น„์šฉ์„ ๊ตฌํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฑํŠธ๋ ˆํ‚น์ด ์ ํ•ฉํ•ด ๋ณด์ธ๋‹ค. ํ•˜์ง€๋งŒ ์ด์ „์— ํ’€์ดํ–ˆ๋˜ ๋ฌธ์ œ์™€ ๋‹ค๋ฅด๊ฒŒ ๋ฐฑํŠธ๋ ˆํ‚น์ด ํƒˆ์ถœํ•  ํฌ์ธํŠธ๋ฅผ depth๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ๋ถ€๋ถ„์„ ์ •ํ•ด์•ผ ํ–ˆ๋‹ค. ํ•ญ์ƒ depth๋กœ๋งŒ ํ’€์ดํ•˜๋‹ค๊ฐ€ ์กฐ๊ธˆ ํ˜ผ๋ž€์Šค๋Ÿฌ์› ๋‹ค. ์šฐ์„  ๋ฐฑํŠธ๋ ˆํ‚น์˜ ํ‹€์„ ์–ด๋Š ์ •๋„ ์ž‘์„ฑํ•ด ๋†“๊ณ  ์–ด๋–ค ๊ฒƒ์„ ๊ตฌํ•ด์•ผ ํ• ์ง€ ์ž‘์„ฑํ•ด ๋ดค๋‹ค.

  • ์˜์–‘์†Œ๋ฅผ ๋„˜๋Š” ์‹์žฌ๋ฃŒ์˜ ์กฐํ•ฉ์ด 1,2,5 = ๋น„์šฉ 30 / 1,3,6,7 = ๋น„์šฉ 10 ์ด๋ ‡๊ฒŒ ๋‚˜์˜ฌ ๊ฒฝ์šฐ 1,3,6,7์„ ์ถœ๋ ฅํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ์กฐํ•ฉ์˜ ์ˆ˜๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ์‹์ด ํ•„์š”ํ•˜๋‹ค.
  • ์ตœ์†Œ ๋น„์šฉ์ด ๊ฐฑ์‹ ๋  ๊ฒฝ์šฐ ์ด์ „ ์‹์žฌ๋ฃŒ์˜ ๋ฒˆํ˜ธ๋ฅผ ์ œ๊ฑฐ ํ›„ ์ƒˆ๋กœ์šด ์กฐํ•ฉ์˜ ์‹์žฌ๋ฃŒ ๋ฒˆํ˜ธ๋ฅผ ๋„ฃ์–ด์•ผ ํ•œ๋‹ค

์†”์งํžˆ ๋‹ค๋ฅธ ๋ถ€๋ถ„์€ ์ ‘๊ทผํ•˜๊ธฐ ์‰ฌ์› ๋‹ค. ํ•˜์ง€๋งŒ ๋ชจ๋“  ์กฐํ•ฉ์„ ์ฐพ์•„๋ณด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ๊ตฌํ˜„์„ ํ•˜๊ธฐ ์–ด๋ ค์›Œ ๊ตฌ๊ธ€๋ง์„ ํ•ด์„œ ์ฐพ์•„๋ดค๋‹ค.

์ฐธ๊ณ  ๋ธ”๋กœ๊ทธ : https://dang2dangdang2.tistory.com/192

 

[JAVA]๋ฐฑ์ค€_19942_๋‹ค์ด์–ดํŠธ

๋ฌธ์ œ๋งํฌ https://www.acmicpc.net/problem/19942 19942๋ฒˆ: ๋‹ค์ด์–ดํŠธ ์‹์žฌ๋ฃŒ N๊ฐœ ์ค‘์—์„œ ๋ช‡ ๊ฐœ๋ฅผ ์„ ํƒํ•ด์„œ ์ด๋“ค์˜ ์˜์–‘๋ถ„(๋‹จ๋ฐฑ์งˆ, ํƒ„์ˆ˜ํ™”๋ฌผ, ์ง€๋ฐฉ, ๋น„ํƒ€๋ฏผ)์ด ์ผ์ • ์ด์ƒ์ด ๋˜์–ด์•ผ ํ•œ๋‹ค. ์•„๋ž˜ ํ‘œ์— ์ œ์‹œ๋œ 6๊ฐ€์ง€

dang2dangdang2.tistory.com

์œ„ ๋ธ”๋กœ๊ทธ์—์„  ์ด๋ ‡๊ฒŒ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์˜€๋‹ค ํ•˜์ง€๋งŒ ์•„๋ฌด๋ฆฌ ๋””๋ฒ„๊ทธ๋ฅผ ๋Œ๋ ค๋ด๋„ ๋‚ด ๋จธ๋ฆฌ๋กœ๋Š” ์ดํ•ด๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•ด ๋ณด์˜€๋‹ค. ์™œ ์ €๋ ‡๊ฒŒ ์‚ฌ์šฉ์„ ํ•˜๋Š”์ง€ ์™€๋‹ฟ์ง€ ์•Š์•˜๋‹ค. ๊ทธ๋ž˜์„œ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผํ•ด๋ณด๋ ค๊ณ  ํ–ˆ๋‹ค.

//ํ•œ๊ฐœ ๊ณ ๋ฅด๋Š” ๊ฒƒ ๋ถ€ํ„ฐ 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๋ฅผ ๋Œ๋ฆฌ๋ฉด ๋œ๋‹ค.

 

17610๋ฒˆ: ์–‘ํŒ”์ €์šธ

๋ฌด๊ฒŒ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ k๊ฐœ์˜ ์ถ”์™€ ๋นˆ ๊ทธ๋ฆ‡์ด ์žˆ๋‹ค. ๋ชจ๋“  ์ถ”์˜ ๋ฌด๊ฒŒ๋Š” ์ •์ˆ˜์ด๊ณ , ๊ทธ๋ฆ‡์˜ ๋ฌด๊ฒŒ๋Š” 0์œผ๋กœ ๊ฐ„์ฃผํ•œ๋‹ค. ์–‘ํŒ”์ €์šธ์„ ํ•œ ๋ฒˆ๋งŒ ์ด์šฉํ•˜์—ฌ ์›ํ•˜๋Š” ๋ฌด๊ฒŒ์˜ ๋ฌผ์„ ๊ทธ๋ฆ‡์— ๋‹ด๊ณ ์ž ํ•œ๋‹ค. ์ฃผ์–ด์ง„ ๋ชจ๋“  ์ถ”

www.acmicpc.net

๋ฌธ์ œ๋ฅผ ๋– ์˜ฌ๋ ค์„œ ํ™œ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค ์œ„ ๋ฌธ์ œ์˜ ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๊ฐ๊ฐ 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]);
    }
}