[문제보기]
2579. 계단 오르기
2579번: 계단 오르기
계단 오르기 게임은 계단 아래 시작점부터 계단 꼭대기에 위치한 도착점까지 가는 게임이다. <그림 1>과 같이 각각의 계단에는 일정한 점수가 쓰여 있는데 계단을 밟으면 그 계단에 쓰여 있는 점
www.acmicpc.net
[풀이과정]
일단 이 문제를 보고 드는 생각은 dp로 풀어야겠다고 생각을 했다. 왜냐하면 결국에는 마지막 계단을 밟았을 때 제일
높은 점수를 찾는 문제이고, 각각 계단을 밟을 수 있는 경우에 대해 제일 높은 값으로 갱신을 해주면 되겠다고
생각했기 때문이다.
문제에서 제시하는 3가지 조건이 있다. 3번째 조건은 신경을 안 써줘도 되지만, 1,2 번째에 대한 조건을 dp의 점화식을
세울 때 신경을 써줘야 되는 부분이다.
첫 번째 조건을 정리를 하면, 계단은 1칸 혹은 2칸씩 오를 수가 있다. 따라서 현재 서 있는 계단을 오를 수 있는 경우는
두 가지가 된다.(1칸을 뛰어서 오는 경우, 2칸을 뛰어서 오는 경우)
그리고 두 번째 조건을 적용을 한다면, 현재 계단이 n번째 계단일 때, 이 계단으로 올 수 있는 경우는,
[n-3]번째 계단에서 [n-1]번째 계단을 밟고 [n]번째 계단으로 오는 경우([n-2]번째 계단을 뛰어넘었다)와
[n-2]번째 계단에서 [n]번째 계단으로 바로 오는 경우가 된다.
예를 들어 [4]번째 계단으로 오는 경우는
[1]번째 계단에서 시작(dp[1)하여 [3]번째 계단을 밟고(+step[3]) [4]번째 계단으로 도착(+step[4])하는 경우 vs
[2]번째 계단에서 시작{dp[2])하여 [4]번째 계단으로 도착(+step[4])하는 경우가 된다.
이를 점화식으로 나타내면
dp[n] = max(dp[n-3] + step[n-1] + step[n] , dp[n-2]+step[n]);
가 된다.
[소스코드]
#include <iostream>
using namespace std;
int step[301] = {0};
int dp[301] = {0};
int main(){
int n;
cin >> n;
for(int i=1; i<=n; i++){
cin >> step[i];
}
dp[1] = step[1];
dp[2] = step[1] + step[2];
for(int i=3; i<=n; i++){
dp[i] = max(dp[i-3]+step[i-1]+step[i], dp[i-2]+step[i]);
}
cout << dp[n];
}
[해결 과정 중 실수한 부분]
처음에는 좀 어렵게 생각을 했다. 현재의 계단으로 올 수 있는 경우를 생각하려고, dp를 2차원 배열로 만들어
한 칸을 뛴 경우, 두 칸을 뛴 경우로 나눠서 생각을 했다.
하다 보다가 점화식이 너무 복잡하게 나와 지우고 다시 생각을 해봤고, dp를 1차원으로 만들어서
생각을 해봤다.
'알고리즘 스터디 > Beakjoon' 카테고리의 다른 글
[백준 2193][C++] 이친수 (0) | 2020.08.29 |
---|---|
[백준 1932][C++] 정수 삼각형 (Silver 1) (0) | 2020.08.29 |
[백준 16235][C++] 나무 재테크 (Gold4) (0) | 2020.08.25 |
[백준 15685][C++] 드래곤 커브 (Gold 4) (0) | 2020.08.25 |
[백준 17144][C++] 미세먼지 안녕! (Gold 5) (0) | 2020.08.25 |