[BOJ] 2579 계단 오르기 - 동적계획법

어떠한 인덱스 N에 도착하기 위한 경우의 수는 두가지 밖에 없다.
두칸 전에서 두칸을 뛰어 오르던지,
한칸전에서 한칸을 뛰어 오르던지.
근데 두칸을 올라서 굳이 한칸을 빼먹어야 될 일은 없다.
그래서 무조건 한칸씩 계속 오르면 최대값이다.
다 올라간게 무조건 최대값이다.
이건 문제가 되질 않는다.
그래서 문제에선 세칸이 연속되면 안된다는 조건을 건다.
두칸전에서 두칸을 뛰어 오르는 경우를 생각해보자.
이건 단순히 N - 2 번째 칸까지의 최대값에서, N 칸을 밟은 거다.
두칸을 올라온 거니 따로 제약사항이 없다.MAX(N) = MAX(N-2) + COST(N)이 나온다.
한칸전에서 한칸을 뛰어 오르는 경우를 생각해보자.
여긴 조건이 있다.따라서 패턴을 강제시킨다.
N - 1 번째 칸에서 한칸을 뛰어 올랐다면, N - 1번째 칸은 밟아야한다.
N - 2 번째 칸은 무조건 밟아서는 안된다. 조건에 위배된다. N번째 칸을 밟고있는 상태라는것을 기억하자.
N - 3 번째 칸은 무조건 밟아야 한다 왜 ? 그래야 두칸을 뛰어올라 N - 1 번째 칸을 밟을수 있다.
N - 1 번째 칸을 밟는 경우엔 반드시 위와 같이 나올수 밖에 없다.단 한가지다. 이 패턴을 강제시킨다.
N - 3 번째까지의 최대값을 구할때 이전패턴이 어떤것인지는
이전에 최대값을 계산할때 비교하고, 적용 되었을 것이다.
따로 신경쓰지 않는다.
패턴을 강제하는건 N - 1 과 N - 2 에 대해서이다.
강제시킨 패턴의 식은 다음과 같이 나온다.
MAX(N) = MAX(N-3) + COST(N) + COST(N-1)

식을 구성할수 있으니, 반복문에 적용해 아래 인덱스부터 차례대로 답을 구한다.
코드는 다음과 같이 작성하였다.
#include <algorithm> #include <iostream> int MaxSumUntil[301] = { 0, }; int Cost[301] = { 0, }; int main() { std::cin.tie(0); std::cout.tie(0); std::cin.sync_with_stdio(false); std::cout.sync_with_stdio(false); int N; std::cin >> N; for (int i = 1; i <= N; ++i) std::cin >> Cost[i]; MaxSumUntil[1] = Cost[1]; MaxSumUntil[2] = Cost[1] + Cost[2]; MaxSumUntil[3] = std::max(Cost[1] + Cost[3], Cost[2] + Cost[3]); for (int i = 4; i <= N; ++i) MaxSumUntil[i] += Cost[i] + std::max(MaxSumUntil[i - 3] + Cost[i - 1], MaxSumUntil[i - 2]); std::cout << MaxSumUntil[N] << std::endl; return 0; }
'알고리즘' 카테고리의 다른 글
[BOJ] 10844 쉬운 계단수 - 동적 계획법 (0) | 2022.01.13 |
---|---|
[BOJ] 1463 1로 만들기 - 메모이제이션 (0) | 2022.01.13 |
[BOJ] 1932 정수 삼각형 - 동적 계획법 (0) | 2022.01.10 |
[BOJ] 12869 뮤탈리스크 - 완전탐색 (0) | 2021.12.03 |
[BOJ] 13902 개업 2 - 동적 계획법 (0) | 2021.12.03 |
댓글
이 글 공유하기
다른 글
-
[BOJ] 10844 쉬운 계단수 - 동적 계획법
[BOJ] 10844 쉬운 계단수 - 동적 계획법
2022.01.13 -
[BOJ] 1463 1로 만들기 - 메모이제이션
[BOJ] 1463 1로 만들기 - 메모이제이션
2022.01.13 -
[BOJ] 1932 정수 삼각형 - 동적 계획법
[BOJ] 1932 정수 삼각형 - 동적 계획법
2022.01.10 -
[BOJ] 12869 뮤탈리스크 - 완전탐색
[BOJ] 12869 뮤탈리스크 - 완전탐색
2021.12.03
댓글을 사용할 수 없습니다.