-
[문제해결을 위한 창의적 알고리즘] 광석 수집 (고급 p.103)알고리즘 2017. 1. 27. 21:00
이 문제는 동적계획법 (Dynamic Programming)을 배울때, 가장 기본적인 유형으로 볼 수 있는 문제이다. 오른쪽과 아래쪽으로만으로 움직일 수 있다는 제약 조건 때문에, 왼쪽의 값과 위쪽의 값을 비교해 가면서 다이내믹 테이블을 업데이트하면서 답을 구해갈 수 있다. 나머지 설명은 책을 참고하면 되겠다.
책을 읽다 보니 한가지 수정했으면 하는 부분이 있는데 바로 106페이지의 T[i][j] 점화식에서 base case로 0 (i=0, j=0)이라고 되어 있는데, mine[0][0]으로 하는 것이 맞을 것 같다.
import java.util.Scanner;
public class Mining103 {
public static int n;
public static int m;
// 책에서는 220까지 하도록 되어 있으나, 최소한의 메모리를 사용하려면 200이 더 좋을 것 같다
// 물론 이것 때문에 아래에서 up, left 변수를 처리해야 하는 번거로움은 생겼다.
public static int[][] arr=new int[200][200];
public static int[][] dt = new int[200][200];
public static int max(int a, int b){
return a > b ? a : b;
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
arr[i][j]=sc.nextInt();
sc.close();
// dt의 위쪽 값과 왼쪽 값을 받아 비교해 보고 더 큰쪽을 택해, arr의 자기 위치 값과 계속 더한다
for (int i = 0; i < n; i++){
for (int j=0; j<m; j++){
int up =0;
int left=0;
if (i>0)
up = dt[i-1][j];
if (j>0)
left = dt[i][j-1];
dt[i][j]=max(up, left)+arr[i][j];
}
}
// 0부터 시작했으므로 n-1, m-1위치값이 답이 된다
System.out.println(dt[n-1][m-1]);
return;
}
}
Big O(n*m)
Github: https://github.com/nevermet/CreativeAlgorithmAdv/blob/master/Mining103.java
'알고리즘' 카테고리의 다른 글
[문제해결을 위한 창의적 알고리즘] 앱 (고급 p.112) (0) 2017.01.28 [문제해결을 위한 창의적 알고리즘] 배낭 문제 (고급 p.107) (0) 2017.01.28 [문제해결을 위한 창의적 알고리즘] 숙직 선생님 (고급 p.97) (0) 2017.01.26 [문제해결을 위한 창의적 알고리즘] Combination (고급 p.87) (0) 2017.01.21 [문제해결을 위한 창의적 알고리즘] 숫자 뒤집기 (고급 p.83) (0) 2017.01.21