[프로그래머스-레벨2]땅따먹기 - Java

iamjinseo·2023년 7월 6일
0

문제풀이-Java

목록 보기
43/53
post-custom-banner


https://school.programmers.co.kr/learn/courses/30/lessons/12913?language=java


문제 설명

땅따먹기 게임을 하려고 합니다. 땅따먹기 게임의 땅(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 이하의 자연수

입출력 예

landanswer
[[1,2,3,5],[5,6,7,8],[4,3,2,1]]16

입출력 예 설명
입출력 예 #1
문제의 예시와 같습니다.


풀이

import java.util.*;

class Solution {
    int solution(int[][] land) {
        int[][] dp = new int[land.length+1][4];
        
        for(int i = 1; i<dp.length; i++){
            for(int j = 0; j<4; j++){
                for(int d=0; d<4; d++){
                    if(d==j) continue;
                    dp[i][j] = Math.max(dp[i-1][d]+land[i-1][j], dp[i][j]);
                }
            }
        }
        
        int ans=0;
        for(int j=0; j<4; j++){
            if(dp[dp.length-1][j]>ans)
                ans = dp[dp.length-1][j];
        }
        return ans;
    }
}

처음에는 조합이라고 생각해서 연속되지 않는 열 조합을 뽑아내어 풀었는데 전부 시간초과가 나버렸다.

결국 구글링 해버렸지만, DP를 이용한다는 아이디어만 얻었을 뿐 코드까지 베끼진 않았다.


결과



후기

//연속 없는 중복 조합으로 열 조합 생성
//모든 열 조합의 합을 구하여 최대값 계산
class Solution {
    int len;
    int[] result = null;
    int[][] coppied;
    int ans = 0;
    
    int solution(int[][] land) {
        coppied = land;
        // System.out.println(Arrays.toString(coppied));
        len = land.length;
        result = new int[len];
        combi(0,0);
        
        return ans;
    }
    
    void combi(int idx, int before){
        // 조합 끝
        if(idx==len){
            int sum = 0;
            for(int i=0; i<len; i++){
                sum += coppied[i][result[i]];
            }
            if(sum > ans)
                ans = sum;
            return;
        }
        
        // 조합 시작
        for(int i=0; i<4; i++){
            if(i==before)
                continue;
            result[idx] = i;
            combi(idx+1, i);
        }
    }
}

조합으로 풀어버린 멍청한 코드 공개.

생각해보니 몇달 전에 비슷한 문제를 풀었던 적이 있다....
난 또 까먹어 버린 것이다..

profile
일단 뭐라도 해보는 중
post-custom-banner

0개의 댓글