https://www.acmicpc.net/problem/2579
2579번: 계단 오르기
계단 오르기 게임은 계단 아래 시작점부터 계단 꼭대기에 위치한 도착점까지 가는 게임이다. <그림 1>과 같이 각각의 계단에는 일정한 점수가 쓰여 있는데 계단을 밟으면 그 계단에 쓰여 있는 점
www.acmicpc.net
계단을 연속으로 세 칸 이상 밟을 수 없으므로, 계단을 마지막에 한 계단 올랐을 때와 두 계단 올랐을 때로 구분한다. 계단을 두 번 이상 연속으로 한 계단씩 올랐을 때는 계단을 세 칸 이상 연속해서 밟은 것이므로 불가능하고, 두 계단씩 오르는 것은 제약이 없다. 따라서 마지막에 한 계단 올랐을 때는 현재 계단의 점수에 직전 계단을 두 계단 올라 도착한 경우를 더하고, 두 계단 올랐을 때는 현재 계단의 점수에 직전 계단을 한 계단, 혹은 두 계단 오른 경우에서 점수가 더 높은 쪽을 더한다. 이 과정을 계단 수만큼 반복한 뒤, 마지막 계단의 두 경우에서 더 큰 점수를 출력하면 된다.
#include <cstdio>
#define MAX_N 300
// stair: 계단의 각 칸이 가진 가중치
// pt[i]: i == 0: 직전에 한 칸 뛰어 연속 두 칸을 밟았을 경우 최댓값
// i == 1: 직전에 두 칸 뛰어 연속 한 칸을 밟았을 경우 최댓값
int stair[MAX_N], pt[2][MAX_N];
int max(int a, int b) { return a > b ? a : b; }
int main() {
// 이동할 계단의 수
int num;
// 문제의 조건을 입력받는다
scanf("%d", &num);
for (int i = 0; i < num; i++) scanf("%d", &stair[i]);
// 총 한 칸 올라간 경우 두 칸 뛸 수는 없다
pt[0][0] = stair[0];
pt[1][0] = 0;
// 총 두 칸 올라간 경우 알고리즘과 다르게 두 번 연속으로 한 칸씩 뛸 수 있다
pt[0][1] = stair[0] + stair[1];
pt[1][1] = stair[1];
// 마지막으로 한 칸을 뛰었을 경우 그 전에 한 칸을 뛰는 것은
// 계단 세 개를 연속으로 밟은 것이므로 불가능
for (int i = 2; i < num; i++) {
pt[0][i] = stair[i] + pt[1][i - 1];
pt[1][i] = stair[i] + max(pt[0][i - 2], pt[1][i - 2]);
}
//직전에 한 칸 뛴 경우와 두 칸 뛴 경우를 비교해 가중치가 큰 쪽을 출력한다
printf("%d\n", max(pt[0][num - 1], pt[1][num - 1]));
return 0;
}
'알고리즘 > 문제 풀이' 카테고리의 다른 글
2581번: 소수 (0) | 2021.12.17 |
---|---|
2580번: 스도쿠 (0) | 2021.12.17 |
2577번: 숫자의 개수 (0) | 2021.12.17 |
2562번: 최댓값 (0) | 2021.12.17 |
2558번: A+B - 2 (0) | 2021.12.17 |