728x90
DFS, BFS 활용 섹션 - (2)
8-5. 동전교환 | DFS
- DFS(L, sum) : 0개부터 시작해서 L개의 동전을 사용했을 때 sum이 문제의 m과 같아지는 경우, 더 작은 min(answer, L); 로 변경하면 된다.
- 동전의 종류는 arr[i]로 받을 건데, 각각의 DFS() 호출은 for문으로 arr[] 내부를 돌면서 각각의 L개 동전을 arr[i]의 동전 종류 사용한 후 sum 값을 보면서 뻗어나가면 된다.
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
/* 8-5. 동전교환
다음과 같이 여러 단위의 동전들이 주어져 있을때
거스름돈을 가장 적은 수의 동전으로 교환해주려면 어떻게 주면 되는가?
각 단위의 동전은 무한정 쓸 수 있다.
*/
public class Main1 {
static int n, m, answer = Integer.MAX_VALUE;
//DFS
public void DFS(int L, int sum, Integer[]arr) {
if(sum > m) return;
if(sum == m) {
answer = Math.min(answer, L);
}else {
for(int i=0; i<n; i++) {
DFS(L+1, sum+arr[i], arr); //재귀 호출
}
}
}
//실행 메인
public static void main(String[] args) {
// TODO Auto-generated method stub
Main1 T = new Main1();
Scanner kb = new Scanner(System.in);
n = kb.nextInt();
//Arrays.sort 사용할 대상은 Integer 객체로 생성한다.
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);
}
}
8-6. 순열 구하기 | DFS
- 이 문제는 전체 n개 중에 m개를 (중복없이) 뽑아야 한다.
- 중복이 없어야 하므로 뽑는 값에 대한 체크용 배열 ch[]가 필요하며
- 각각 m개씩 뽑은 값을 띄울 pm[] 도 필요하다.
- DFS(L) => pm[L]의 L번째 위치에 뽑을 숫자를 for(i~n)까지 하나씩 맞춰가면서 뽑고,
- L이 m이 되면 pm[] 자리에 담을 숫자를 다 뽑은 거다.
import java.util.Scanner;
/* 8-6. 순열 구하기*/
public class Main2 {
static int n, m;
static int[] ch, pm, arr;
//중복 없게 ch[]로 선택값 방문 체크하고,
//뽑은 값은 pm[]에 담는다.
//DFS
public void DFS(int L) {
if(L == m) {
for(int i=0; i<m; i++) System.out.print(pm[i]+ " ");
System.out.println();
}else {
for(int i=0; i<n; i++) {
//중복 없이 뽑아야 하므로 방문 전인 i 에 대하여
if(ch[i] == 0) {
pm[L] = arr[i];//뽑은 수 pm의 L번째 칸에 담고
ch[i] = 1;//i번쨰 수 뽑았음 방문 체크
DFS(L+1); // 재귀 호출
//복귀주소
ch[i]=0;//다음 가지로도 가야하니 이번 가지에ㅔ서 Back
}
}
}
}
//실행 메인
public static void main(String[] args) {
// TODO Auto-generated method stub
Main2 T = new Main2();
Scanner kb = new Scanner(System.in);
n = kb.nextInt();
m = kb.nextInt();
arr=new int[n];
for(int i=0; i<n; i++) arr[i] = kb.nextInt();
ch = new int[n];
pm = new int[m]; //각각 m개의 숫자 뽑으니까
T.DFS(0);
}
}
8-7. 조합의 경우의 수 (메모이제이션)
⬛ 메모이제이션 (Memoization) 이란?
- 동일한 계싼을 반복해야 할 때 이전에 계산했던 값들을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 할 수 있는 방법이다.
- 동적 계획법의 핵심이 되술
import java.util.Scanner;
/* 8-7. 조합의 경우수 (메모이제이션) */
public class Main3 {
//메모이제이션 사용
int[][]dy = new int[35][35];
//DFS
public int DFS(int n, int r) {
if(dy[n][r] > 0) return dy[n][r];
if(n==r || r==0) return 1;
else {
return dy[n][r] = DFS(n-1, r-1) + DFS(n-1, r);
}
}
//실행 메인
public static void main(String[] args) {
// TODO Auto-generated method stub
Main3 T = new Main3();
Scanner kb =new Scanner(System.in);
int n = kb.nextInt();
int r = kb.nextInt();
System.out.println(T.DFS(n, r));
}
}
728x90
'알고리즘 이론 [개념] > [개념] 코테 알고리즘 공부 - 시즌 1' 카테고리의 다른 글
DFS, BFS 활용 섹션 -(4) (0) | 2023.03.28 |
---|---|
DFS, BFS 활용 섹션 - (3) (0) | 2023.03.27 |
DFS, BFS 활용 섹션 - (1) (0) | 2023.03.23 |
그래프 관련 정리 -(1) (0) | 2023.03.22 |
DFS, BFS 개념 -(2) (0) | 2023.03.21 |