문제설명
더보기
위와 같은 삼각형의 꼭대기에서 바닥까지 이어지는 경로 중, 거쳐간 숫자의 합이 가장 큰 경우를 찾아보려고 합니다. 아래 칸으로 이동할 때는 대각선 방향으로 한 칸 오른쪽 또는 왼쪽으로만 이동 가능합니다. 예를 들어 3에서는 그 아래칸의 8 또는 1로만 이동이 가능합니다.
삼각형의 정보가 담긴 배열 triangle이 매개변수로 주어질 때, 거쳐간 숫자의 최댓값을 return 하도록 solution 함수를 완성하세요.
문제풀이
i/j | 0 | 1 | 2 | 3 | 4 |
0 | 7 | ||||
1 | 3 | 8 | |||
2 | 8 | 1 | 0 | ||
3 | 2 | 7 | 4 | 4 | |
4 | 4 | 5 | 2 | 6 | 5 |
입력 값을 반대로 행렬로 나타낸 테이블
위의 테이블을 triangle 테이블, 최대값을 넣어준 테이블은 dp 테이블이라고 부른다.
dp[0][0]은 고정이며 , 아래로 내려 가면서 최대값을 찾아서 또다른 테이블에 넣어 최종적으로 가장 아래에 있는 최대값을 출력을 하는 방법으로 해결했다.
위에서 내려오면서 더하면 규칙이 보이게 되는데 총 3가지 규칙이 있다.
1. j =0 일 때
dp[i][0] = triangle[i][0] + dp[i-1][0]
2. i=j 일 때
dp[i][j] = triangle[i][j]+ dp[i-1][j-1]
3. 중간에 겹치는 부분
이 부분은 잠깐 설명이 필요하다. 예를들면 dp[2][1]은 dp[1][0] , dp[1][1] 두개의 값과 겹친다. 따라서 두 값 중에서 최대값을 골라서 더해준다.
dp[i][j] = triangle[i][j] + Math.max(dp[i - 1][j - 1], dp[i - 1][j]);
3가지 케이스로 나눠서 값을 코드를 짜주면 된다.
class Solution {
public int solution(int[][] triangle){
int [][] dp = new int[triangle.length][triangle.length];
dp [0][0] = triangle[0][0];
int answer=0;
for(int i=1; i<triangle.length; i++){
dp[i][0] = triangle[i][0] + dp[i - 1][0];
dp[i][i] = triangle[i][i] + dp[i - 1][i - 1];
for (int j=1; j<= i; j++){
// 이 부분에서 j<triangle.length; 보다는 i로 하는게 효율이 좋다. 어차피 삼각형이기 때문에 i보다 큰 숫자는 낭비다.
dp[i][j] = triangle[i][j] + Math.max(dp[i - 1][j - 1], dp[i - 1][j]);
}
}
answer = 0;
for (int i = 0; i < triangle.length; i++) {
answer = Math.max(answer, dp[triangle.length - 1][i]);
}
return answer;
}
}
'Etc. > Coding Test' 카테고리의 다른 글
[백준] 2023번 신기한 소수 찾기 (2) | 2022.06.15 |
---|---|
[백준] 11399번 ATM 인출 시간 계산하기 (0) | 2022.05.27 |
[백준] 2164번 카드 게임 (0) | 2022.05.16 |
[백준]1874번 스택으로 오름차순 수열 만들기 (4) | 2022.05.13 |
[백준] 1253번 '좋은 수' 구하기 (0) | 2022.05.11 |