부분집합 문제와는 다르게 동전을 여러개 쓸 수 있다.
여기선 해당 인덱스의 동전을 사용한다. 라고 재귀호출
L == n 이 되면 모두 1원으로 바꾸어주는 것 ~ 5원으로 바꾸어주는 것에 대한 조합(?)들이 만들어진다.
★구해둔 동전의 갯수가 있을 때 그 갯수보다 많이 거슬러주는 부분을 찾아볼 필요가 없다.
BFS가 좀 더 맞는답.
1.DFS
import java.util.*;
public class Main {
static int n, m, answer = Integer.MAX_VALUE;
//L을 동전의 갯수,sum을 L개의 동전의 총합이라 생각
public void DFS(int L, int sum, Integer[] arr) {
//동전의 총합이 m보다 크면 만들 수 없음
if(sum > m) return;
//이미 구해둔 동전의 최소 갯수보다 같거나 더 많이 갯수를 탐색할 필요 없음
if(L>=answer) return;
if(sum == m) {
answer = Math.min(answer, L);
}
else {
for(int i = 0; i < n; i++) {
//동전을 n가닥으로 계속 뻗어나가면서 찾아보기
//동전을 사용한다.로 생각해도 됨★
DFS(L+1, sum+arr[i], arr);
}
}
}
public static void main(String[] args) {
Main T = new Main();
Scanner kb = new Scanner(System.in);
n = kb.nextInt();
Integer[] arr = new Integer[n];
for(int i = 0; i < n; i++) {
arr[i] = kb.nextInt();
}
//배열 내림차순
Arrays.sort(arr, Collections.reverseOrder());
m = kb.nextInt();
T.DFS(0, 0, arr);
System.out.println(answer);
}
}
2.BFS
import java.util.*;
public class Main {
static int n, m, answer;
static int[] dis,ch;
public static void main(String[] args) {
Main T = new Main();
Scanner kb = new Scanner(System.in);
n = kb.nextInt();
dis = new int[n];
ch = new int[501];
for(int i = 0; i < n; i++) dis[i] = kb.nextInt();
m = kb.nextInt();
T.solution(1);
System.out.println(answer);
}
private void solution(int L) {
Queue<Integer> q = new LinkedList<>();
//일단 동전들 큐에 넣어놓기
for(int i = 0; i < n; i++) q.offer(dis[i]);
while(!q.isEmpty()) {
int len = q.size();
System.out.println(q);
//q사이즈 만큼돌기
for(int i = 0; i < len; i++) {
int won = q.poll();
//동전의 갯수만큼 돌기
for(int j = 0; j < dis.length; j++) {
int nextWon = won + dis[j];
if (nextWon == m) {
answer = L + 1;
return;
}
if(ch[nextWon] == 0 && nextWon <= 500) {
ch[nextWon] = 1;
q.offer(nextWon);
}
}
}
L++;
}
}
}
'Algorithm > inflearn' 카테고리의 다른 글
조합수(메모이제이션) (0) | 2021.10.04 |
---|---|
순열 구하기(DFS) (0) | 2021.10.04 |
중복순열 구하기(DFS) (0) | 2021.10.03 |
최대점수 구하기(DFS) (0) | 2021.10.03 |
바둑이 승차(DFS) (0) | 2021.10.03 |