Problem Solving/백준 1일 1커밋
백준 2579 계단 오르기
HWAN JJ
2022. 1. 11. 20:51
https://www.acmicpc.net/problem/2579
2579번: 계단 오르기
계단 오르기 게임은 계단 아래 시작점부터 계단 꼭대기에 위치한 도착점까지 가는 게임이다. <그림 1>과 같이 각각의 계단에는 일정한 점수가 쓰여 있는데 계단을 밟으면 그 계단에 쓰여 있는 점
www.acmicpc.net
<입력>
입력의 첫째 줄에 계단의 개수가 주어진다.
둘째 줄부터 한 줄에 하나씩 제일 아래에 놓인 계단부터 순서대로 각 계단에 쓰여 있는 점수가 주어진다. 계단의 개수는 300이하의 자연수이고, 계단에 쓰여 있는 점수는 10,000이하의 자연수이다.
<규칙>
- 계단은 한 번에 한 계단씩 또는 두 계단씩 오를 수 있다. 즉, 한 계단을 밟으면서 이어서 다음 계단이나, 다음 다음 계단으로 오를 수 있다.
- 연속된 세 개의 계단을 모두 밟아서는 안 된다. 단, 시작점은 계단에 포함되지 않는다.
- 마지막 도착 계단은 반드시 밟아야 한다.
<출력>
첫째 줄에 계단 오르기 게임에서 얻을 수 있는 총 점수의 최댓값을 출력한다.
<후기>
전형적인 DP 문제, 혹시 DP를 처음 접한다면 연습문제로 적절한거 같다.
규칙들을 이용해서 i번째 계단에서 얻을 수 있는 최대값을 구해, 해당 값을 통해 i+1, i+2 번째 계단의 최대값을 구하면 된다.
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
#include <algorithm>
#include <memory.h>
using namespace std;
int D1[301], D2[301], stair[301];
int main(void) {
int n;
stair[0] = D1[0] = D2[0] = 0;
// 1. 계단은 한 번에 1개 또는 2개씩 오를 수 있다.
// 2. 연속된 3개의 계단을 모두 밟아서는 안 된다.
// 3. 마지막 도착 계단을 밟아야 한다.
// DP + 연속 계단 개수 고려
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &stair[i]);
}
if (n == 1) {
printf("%d", stair[1]);
return 0;
}
// 한칸 연속 불가능 (i-1번재 칸에서 한칸 전진해서 도달)
D1[1] = stair[1]; D1[2] = stair[1] + stair[2];
// 가능 (i-2번째 칸에서 2칸 전진해서 도달)
D2[1] = 0; D2[2] = stair[2];
for (int i = 3; i <= n; i++) {
D1[i] = D2[i - 1] + stair[i];
D2[i] = max(D1[i - 2], D2[i-2]) + stair[i];
}
printf("%d", max(D1[n], D2[n]));
return 0;
}