


Dynamic - Procraming(DP)문제로 푸는 방법(공식)만 알면 풀어낼 수 있다.
문제 이해
이 문제에서 사용되는 변수는 아래와 같다.
int n : 계단의 수
int[] stair : 각 계단이 가지고 있는 값
int[] dp : 조건에 따라 누적되는 계단의 값
문제에는 아래와 같은 조건이 있다.
위의 조건을 충족한다는 전제 하에 0, 1, 2번째 자리에는 고정 값이 입력되어야 한다.
dp[0] = stair[0]
: 0번째 계단의 값이 dp에 그대로 입력됨
dp[1] = Math.max(stair[0] + stair[1], stair[1])
: 계단 0번째, 1번째 값을 더한 것과 only 두 번째 값 중 더 큰 것을 dp[1]에 넣음
dp[2] = Math.max(stair[0] + stair[2], stair[1] + stair[2])
: 계단 0 + 계단 2와 계단 1 + 계단 2의 값 중 더 큰 값을 dp[2]에 넣음
위의 고정값은 계단의 최댓값을 구하는 방식과 비교하면 알 수 있다.
현재 위치가 계단 3 일 때, 연속으로 3개의 계단을 오르지 않고 구할 수 있는 최댓값의 방식은
이는 현재 위치가 i일 때 dp[i] = Math.max(dp[i-2] + stair[i], dp[i-3] + stair[i-1] + stair[i]) 로 나타낼 수 있다.
코드 이해
먼저 int형 배열 stair에 계단의 값을 입력받은 후 dp에 값을 저장하는 방식으로 작성했다.
주의할 점 : dp의 0, 1, 2번째에는 고정값을 부여한다.
이 말인 즉슨, 어떤 수(ex. 1)가 들어와도 3개의 배열은 보장되어야 한다는 의미이다.
>> dp 배열 선언 시 n+3을 입력하여 3개의 공간은 보장되도록 한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class App {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[] stair = new int[n + 3];
int[] dp = new int[n + 3];
for (int i = 0; i < n; i++) {
stair[i] = Integer.parseInt(br.readLine());
}
// 아래에서 i-3하려면 최소 3개 만들어져있어야 함
dp[0] = stair[0];
dp[1] = Math.max(stair[0] + stair[1], stair[1]);
dp[2] = Math.max(stair[0] + stair[2], stair[1] + stair[2]);
for (int i = 3; i < n; i++) {
dp[i] =
Math.max(dp[i - 3] + stair[i - 1] + stair[i], dp[i - 2] + stair[i]);
// stair : 10 20 15 25 10 20
// dp : 10 max(10, 20) max(25, 20) max(25, 35) max(30+25, 10+15+25)
}
System.out.println(dp[n - 1]);
}
}
한줄평
dp문제 중 풀다가 정말 포기할까 생각이 드는 문제였다.
그만큼 내 수준에서 혼자 풀어내기엔 어려운 문제였고, 주변의 조언으로 dp는 해설을 보더라도 많이 접하고 풀어야 알게되는 문제라고해서 이해할 수 있었다.
이 문제를 풀고 있는 다른 백준유저도 혼자 끙끙대기 보다는 여러 문제를 접해보면서 dp에 대한 이해도를 키워나갈 수 있었으면 좋겠다.