ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 2096 내려가기
    Algorithm/DP 2022. 9. 16. 16:20
    728x90

    골드 5 난이도의 dp문제이다.

     

    문제를 처음 읽으면 굉장히 간단한 dp문제로 보인다.

     

     

    max_dp[i][j] => i행 j열까지 내려왔을 때, 점수들의 합이 가장 큰 값
    min_dp[i][j] => i행 j열까지 내려왔을 때, 점수들의 합이 가장 작은 값

     

     

    1. 하지만 메모리 제한이 4MB이기 때문에, max_dp와 min_dp를 넉넉하게 최대값인 100001 * 4로 잡는 순간

     

    메모리 초과가 뜨게 된다.

     

    그래서 조금 더 생각을 해 보면, 딱 2개의 row만 필요함을 알 수 있다.

     

    첫 row는 현재 행 까지의 최대(최소)값 들을,

    다음 row는 해당 행 까지의 최대(최소)값을 넣어주고

     

    다음 행을 조사하기 직전에, 마지막 row의 모든 값들을 첫 row로 이동 해 주면 되는 것이다.

     

    따라서, 2 * 3 배열로도 충분히 풀 수 있는 문제이다.

     

     

     

    2. 또한, n이 1인 경우에도 처리를 해 주어야 한다.

     

    따라서 처음 map을 입력 받을 때, max_dp와 min_dp의 첫 행을 map의 첫 행의 값들과 동일하도록 초기화 해 주면 된다.

    #include <iostream>
    #include <algorithm>
    #include <limits.h>
    using namespace std;
    
    int map[100001][3];
    int max_dp[2][3];
    int min_dp[2][3];
    int main(){
        int n;
        cin >> n;
        for(int i = 1; i <= n; i++){
            for(int j = 0; j < 3; j++){
                cin >> map[i][j];
                if(i == 1){
                    max_dp[i][j] = min_dp[i][j] = map[i][j];
                }
                if(i == 2) {
                    min_dp[i-1][j] = INT_MAX;
                }
            }
        }
        for(int i = 1; i <= n; i++){
            for(int j = 0; j < 3; j++){
                if(j==0){
                    max_dp[1][j] = max(max_dp[0][j] + map[i][j], max_dp[1][j]);
                    max_dp[1][j+1] = max(max_dp[0][j] + map[i][j+1], max_dp[1][j+1]);
                    min_dp[1][j] = min(min_dp[0][j] + map[i][j], min_dp[1][j]);
                    min_dp[1][j+1] = min(min_dp[0][j] + map[i][j+1], min_dp[1][j+1]);
                }
                else if(j == 2){
                    max_dp[1][j-1] = max(max_dp[0][j] + map[i][j-1], max_dp[1][j-1]);
                    max_dp[1][j] = max(max_dp[0][j] + map[i][j], max_dp[1][j]);
                    min_dp[1][j-1] = min(min_dp[0][j] + map[i][j-1], min_dp[1][j-1]);
                    min_dp[1][j] = min(min_dp[0][j] + map[i][j], min_dp[1][j]);
                } else {
                    max_dp[1][j] = max(max_dp[0][j] + map[i][j], max_dp[1][j]);
                    max_dp[1][j+1] = max(max_dp[0][j] + map[i][j+1], max_dp[1][j+1]);
                    max_dp[1][j-1] = max(max_dp[0][j] + map[i][j-1], max_dp[1][j-1]);
                    min_dp[1][j] = min(min_dp[0][j] + map[i][j], min_dp[1][j]);
                    min_dp[1][j+1] = min(min_dp[0][j] + map[i][j+1], min_dp[1][j+1]);
                    min_dp[1][j-1] = min(min_dp[0][j] + map[i][j-1], min_dp[1][j-1]);
                }
            }
            for(int j = 0; j < 3; j++){
                max_dp[0][j] = max_dp[1][j];
                max_dp[1][j] = 0;
                min_dp[0][j] = min_dp[1][j];
                min_dp[1][j] = INT_MAX;
            }
        }
        int max_answer = 0; int min_answer = INT_MAX;
        for(int i = 0; i < 3; i++){
            max_answer = max(max_answer, max_dp[0][i]);
            min_answer = min(min_answer, min_dp[0][i]);
        }
        cout << max_answer << ' ' << min_answer;
        return 0;
    }

    'Algorithm > DP' 카테고리의 다른 글

    [프로그래머스] 정수 삼각형  (0) 2022.01.02
    백준 2839 설탕 배달  (0) 2021.11.13

    댓글

Designed by Tistory.