BackTracking, DFS
문제 상세보기
Flow.
- 모든 경우의 수를 검사해서 조건에 맞는 경우를 카운트해서 출력해주는 알고리즘입니다.
- 리스트 & 정렬 사용
- 정렬을 사용함으로써 운동키트 효과가 작은 순서대로 정렬시킬수 있습니다.
- 작은 순서대로 정렬한다면 감소량 K보다 작은 경우의 수들이 빠르게 걸러지고 탐색을 하지 않음으로 백트래킹이 가능합니다.
- backTracking(int sum, int depth)
- depth == n - 1 에 도달하면 하나의 경우의 수는 모두 탐색했음으로 카운트++ & 탈출조건을 만들어줍니다.
- 반복문에서 recursion을 통해 방문하지 않았고, 합계(500) + 운동키트 효과 - 감소량이 500 이상인 경우만 탐색합니다.
- 방문한 운동키트는 true로 바꾸어 줍니다.
- visited[i] = false;
- 해당 (arr.get(i)) 운동키트를 선택한 모든 경우의 수를 탐색했기 때문에 첫번째 운동키트 사용 여부를 다시 원상복귀 해주어야 합니다.
Code.
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
import java.util.stream.IntStream;
public class Main {
static int n;
static int k;
static int count;
static List<Integer> arr;
static boolean[] visited;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt(); //운동키트 갯수 & n 일
k = scanner.nextInt(); //감소량
arr = new ArrayList<>();
IntStream.range(0, n).forEach(i -> arr.add(scanner.nextInt()));
arr.sort(Comparator.naturalOrder());
visited = new boolean[n];
count = 0;
backTracking(500, 0);
System.out.println(count);
}
private static void backTracking(int sum, int depth) {
if (depth == n - 1) {
count++;
return;
}
for (int i = 0; i < n; i++) {
if (!visited[i] && sum + arr.get(i) - k >= 500) {
visited[i] = true;
backTracking(sum + arr.get(i) - k, depth + 1);
visited[i] = false;
}
}
}
}
Leave a comment