본문 바로가기
Algorithm/동적계획법(DP)

2579 계단 오르기

by neohtux 2020. 1. 22.
728x90

https://www.acmicpc.net/problem/2579

 

2579번: 계단 오르기

계단 오르기 게임은 계단 아래 시작점부터 계단 꼭대기에 위치한 도착점까지 가는 게임이다. <그림 1>과 같이 각각의 계단에는 일정한 점수가 쓰여 있는데 계단을 밟으면 그 계단에 쓰여 있는 점수를 얻게 된다. 예를 들어 <그림 2>와 같이 시작점에서부터 첫 번째, 두 번째, 네 번째, 여섯 번째 계단을 밟아 도착점에 도달하면 총 점수는 10 + 20 + 25 + 20 = 75점이 된다. 계단 오르는 데는 다음과 같은 규칙이 있다. 계단은 한 번에 한 계단씩

www.acmicpc.net

계단 오르기 성공

 

시간 제한메모리 제한제출정답맞은 사람정답 비율

1 초 128 MB 50095 20106 14701 39.415%

문제

계단 오르기 게임은 계단 아래 시작점부터 계단 꼭대기에 위치한 도착점까지 가는 게임이다. <그림 1>과 같이 각각의 계단에는 일정한 점수가 쓰여 있는데 계단을 밟으면 그 계단에 쓰여 있는 점수를 얻게 된다.

예를 들어 <그림 2>와 같이 시작점에서부터 첫 번째, 두 번째, 네 번째, 여섯 번째 계단을 밟아 도착점에 도달하면 총 점수는 10 + 20 + 25 + 20 = 75점이 된다.

계단 오르는 데는 다음과 같은 규칙이 있다.

  1. 계단은 한 번에 한 계단씩 또는 두 계단씩 오를 수 있다. 즉, 한 계단을 밟으면서 이어서 다음 계단이나, 다음 다음 계단으로 오를 수 있다.
  2. 연속된 세 개의 계단을 모두 밟아서는 안 된다. 단, 시작점은 계단에 포함되지 않는다.
  3. 마지막 도착 계단은 반드시 밟아야 한다.

따라서 첫 번째 계단을 밟고 이어 두 번째 계단이나, 세 번째 계단으로 오를 수 있다. 하지만, 첫 번째 계단을 밟고 이어 네 번째 계단으로 올라가거나, 첫 번째, 두 번째, 세 번째 계단을 연속해서 모두 밟을 수는 없다.

각 계단에 쓰여 있는 점수가 주어질 때 이 게임에서 얻을 수 있는 총 점수의 최댓값을 구하는 프로그램을 작성하시오.

입력

입력의 첫째 줄에 계단의 개수가 주어진다.

둘째 줄부터 한 줄에 하나씩 제일 아래에 놓인 계단부터 순서대로 각 계단에 쓰여 있는 점수가 주어진다. 계단의 개수는 300이하의 자연수이고, 계단에 쓰여 있는 점수는 10,000이하의 자연수이다.

출력

첫째 줄에 계단 오르기 게임에서 얻을 수 있는 총 점수의 최댓값을 출력한다.

예제 입력 1 복사

6 10 20 15 25 10 20

예제 출력 1 복사

75

출처

Olympiad > 한국정보올림피아드 > 한국정보올림피아드시․도지역본선 > 지역본선 2006 > 초등부 4번

 

문제 접근

규칙에 의거하여 점화식을 세우자.

  1. 계단은 한 번에 한 계단씩 또는 두 계단씩 오를 수 있다. 즉, 한 계단을 밟으면서 이어서 다음 계단이나, 다음 다음 계단으로 오를 수 있다.
  2. 연속된 세 개의 계단을 모두 밟아서는 안 된다. 단, 시작점은 계단에 포함되지 않는다.
  3. 마지막 도착 계단은 반드시 밟아야 한다.

마지막 계단까지의 최대 값으로, 마지막 항을 N으로 두었다.

3번의 조건에 의해 안밟는 경우는 제외하고

마지막 계단을 밟기 바로 전 상태를  조건으로 둔다.

 

 1. 바로 전전 단계에서 2단점프로 N에 도착하는 시점

 2. 바로 전    단계에서 1단점프로 N에 도착하는 시점

 

1번의 점화식은 바로 전 단계의 누적 점수를 dp[n-2]로 정의( 끝 항이 n이 라고 가정)

 -> dp[n] (누적점수) = dp[n-2]+score_arr[n] (전전 상태의 누적합 + 끝 계단의 점수)

 

2. 2번에서 실수를 안하기 위해서, 2번의 조건에 유의하여야한다.

 -> dp[n] = dp[n-1] + score_arr[n] 으로 하면 테스트케이스 오답이 나온다. (처음에 이렇게함..)

 -> 바로 전단계를 밟고 N(끝 계단)을 밟으려면 전전단계를 밟으면 안된다.

 -> 따라서, dp[n]= dp[n-3] + score_arr[n-1]+score_arr[n] (전전전 상태 누적 합 + 2단점프 계단(전 계단) + 끝 계단)

 

<개인 풀이>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include<stdio.h>
#include<algorithm>
 
int score_arr[300]; //입력 받을 계단 점수
 
int dp[300]; //계단 최대의 값 300층 -> max(조건1,조건2)의 dp[299]
using namespace std;
int get_max(int a, int b)
{
    if (a > b) return a;
    else if (a < b) return b;
}
int main(void)
{
    int n = 0;
    int score = 0;
    scanf("%d"&n);
 
    for (unsigned short i = 0; i < n; ++i)
    {
        scanf("%d"&score);
        score_arr[i] = score;
    }
    /* 처음 계단, 위치 경우의수 초기화*/
    dp[0= score_arr[0];
    dp[1= get_max((score_arr[0+ score_arr[1]), score_arr[1] );
    dp[2= get_max((score_arr[0+ score_arr[2]), (score_arr[1+ score_arr[2]));
    // 바로전 연속 1칸씩 3회이상 갈수없음
    
    // n 이전 계단
    // dp[n] = dp[n-3]+score_arr[n-1]+score_arr[n];
 
    // n 이전전 계단
    // dp[n] = dp[n-2]+score_arr[n];
    for (unsigned short i = 3; i < n; ++i)
    {
        dp[i] = get_max((dp[i - 3+ score_arr[i - 1+ score_arr[i]), (dp[i - 2+ score_arr[i]));
    }
 
    printf("%d\n", dp[n - 1]);
 
    
    
    return 0;
}
 
 
300x250

'Algorithm > 동적계획법(DP)' 카테고리의 다른 글

10844 쉬운 계단수  (0) 2020.03.17
11727 2 x n 타일링 2  (0) 2020.03.17
1149 RGB거리  (0) 2020.01.22
9095 1,2,3 더하기  (0) 2020.01.20
11726 2xn타일링  (0) 2020.01.20

댓글