본문 바로가기
Programmers/C++

[C++] 프로그래머스 :: 땅따먹기

by Sin_ 2021. 10. 17.
728x90

안녕하세요 뚜디 입니다 :)

코딩테스트 연습 - 땅따먹기 | 프로그래머스 (programmers.co.kr)

 

코딩테스트 연습 - 땅따먹기

땅따먹기 게임을 하려고 합니다. 땅따먹기 게임의 땅(land)은 총 N행 4열로 이루어져 있고, 모든 칸에는 점수가 쓰여 있습니다. 1행부터 땅을 밟으며 한 행씩 내려올 때, 각 행의 4칸 중 한 칸만 밟

programmers.co.kr

< 프로그래머스 - 땅따먹기 (lv2) >


1. 연습 문제

2. 문제 풀이

3. 소스 코드

4. 결과


1. 연습 문제
  • 문제 설명
땅따먹기 게임을 하려고 합니다. 땅따먹기 게임의 땅(land)은 총 N행 4열로 이루어져 있고, 모든 칸에는 점수가 쓰여 있습니다. 1행부터 땅을 밟으며 한 행씩 내려올 때, 각 행의 4칸 중 한 칸만 밟으면서 내려와야 합니다. 단, 땅따먹기 게임에는 한 행씩 내려올 때, 같은 열을 연속해서 밟을 수 없는 특수 규칙이 있습니다.
예를 들면,
| 1 | 2 | 3 | 5 |
| 5 | 6 | 7 | 8 |
| 4 | 3 | 2 | 1 |
로 땅이 주어졌다면, 1행에서 네번째 칸 (5)를 밟았으면, 2행의 네번째 칸 (8)은 밟을 수 없습니다.
마지막 행까지 모두 내려왔을 때, 얻을 수 있는 점수의 최대값을 return하는 solution 함수를 완성해 주세요. 위 예의 경우, 1행의 네번째 칸 (5), 2행의 세번째 칸 (7), 3행의 첫번째 칸 (4) 땅을 밟아 16점이 최고점이 되므로 16을 return 하면 됩니다.
  • 제한 조건
행의 개수 N : 100,000 이하의 자연수
열의 개수는 4개이고, 땅(land)은 2차원 배열로 주어집니다.
점수 : 100 이하의 자연수
  • 입출력 예
land answer
[[1,2,3,5],[5,6,7,8],[4,3,2,1]] 16

 

2. 문제 풀이
이번 문제는 다이나믹 프로그래밍(DP) 기법을 통해 풀어야하는 문제입니다.
다이나믹 프로그래밍 기법을 통해 풀기위해서는 점화식을 반드시 만들어야한다.

🔶[점화식]🔶 dp[i][j]는 내려오면서 land[i][j]에 도달하는 데까지 가질 수 있는 최댓값이라고 정의
1. dp[0][j] = land[i][j]
   - i = 0 첫 행
   - 위에서 내려올게 없으므로 아래로 내려가 도달하는데까지 가질 수 있는 최댓값 = 자기 자신
2. dp[i][j] = land[i][j] + Max(dp[i-1][k])
   - 도달한 위치까지 내려오는데 가질수 있는 최댓값
      = 지금 현재의 값 + 이전 행의 열까지 내려오는데 가질수 있는 3개의 최댓값 중 최댓값
   - i = 1~land.size()-1 : 두번째 행~마지막 행
   - Max(dp[i-1][k]) 이전 행의 자리까지의 최댓값
      -> j != k 이어야 한다 (동일한 열에서 내려올 수 없음)
      -> dp[5][2] 를 구하려고 하고 있다면 dp[5][2] = land[5][2] + Max(dp[4][0] + dp[4][1] + dp[4][3]) 이 된다.

< 다이나믹 프로그래밍 - DP >

[C++] 동적 계획법 Dynamic Programming(DP) 사용법 (tistory.com)

 

[C++] 동적 계획법 Dynamic Programming(DP) 사용법

안녕하세요 뚜디 입니다:) < 동적 계획법 Dynamic Programming (DP) > 1. 동적 계획법이란? 2. 동적 계획법 사용 3. 동적 계획법 예시 1. 동적 계획법이란? 다이나믹 프로그래밍(Dynamic Programmin)은 프로그래..

sindh718.tistory.com

 

3. 소스 코드
  • 소스코딩 - 실패
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

int solution(vector<vector<int> > land)
{
    int answer = 0;
    int max = 0;
    int temp = -1, pre = -1;

    for (int i = 0; i < land.size(); i++) {
        int max = 0;
        for (int j = 0; j < land[0].size(); j++) {
            if (max < land[i][j] && pre != j) {
                max = land[i][j];
                temp = j;
            }
        }
        pre = temp;
        answer += max;
    }

    return answer;
}
  • 다이나믹 프로그래밍(DP) - 성공
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int solution(vector<vector<int>> land)
{
    int answer = 0;
    vector<vector<int>> dp(land.size(), vector<int>(4));

    for (int i = 0; i < 4; i++)
        dp[0][i] = land[0][i];

    for (int i = 1; i < land.size(); i++) {
        for (int j = 0; j < 4; j++) {
            int max = 0;
            for (int k = 0; k < 4; k++) {
                if (k == j) continue;
                if (max < dp[i - 1][k])
                    max = dp[i - 1][k];
            }
            dp[i][j] = land[i][j] + max;
        }
    }

    answer = *max_element(dp.back().begin(), dp.back().end());

    return answer;
}

 

4. 결과

728x90