https://programmers.co.kr/learn/courses/30/lessons/12913
[ 문제 설명 ]
문제 설명
땅따먹기 게임을 하려고 합니다.
땅따먹기 게임의 땅(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 하면 됩니다.
[ 제한 사항 ]
[ 입출력 예시 ]
land | answer |
---|---|
[[1,2,3,5],[5,6,7,8],[4,3,2,1]] | 16 |
[[4, 3, 2, 1], [2, 2, 2, 1], [6, 6, 6, 4], [8, 7, 6, 5]] | 20 |
[ 잘못된 접근 ]
문제를 보고 열(Row)이 겹치지 않게 각 행마다 최댓값을 더해나가면 풀 줄 알았다.
대신 행(i)에 max값이 여러개 있을 경우 다음 행(i+1)은 자유롭게 이전 열에 신경쓰지 않고 자유롭게 고를 수 있도록 만들었지만 접근이 잘못 되었다.
이럴 경우 가장 큰 값을 고르고 열에 제한을 주었을 때, 다음 행 같은 열에 큰 수가 있음에도 고르지 못하는 경우가 발생한다.
[ 다른 사람 풀이를 보고 푼 코드 ]
- 기존에 입력 받은 배열(land)에 본인의 행과 그 이전 또는 다음 행 다른 열에 존재하는 값들의 합 중 가장 큰 경우의 수를 골라 그 행의 열에 최댓값들을 누적시킨다.
- 이를 행의 길이 끝까지 반복하여 같은 열이 아닌 다른 열들의 합을 최종적으로 구한다.
마지막 행을 나타낼 배열(temp)를 선언하고, Arrays.sort(배열명);을 하여 최댓값을 마지막 인덱스로 보낸다.
- answer에 마지막 인덱스 값을 담아서 answer을 반환한다.
[ 잘못된 접근으로 풀어 본 코드 ]
class Solution {
//가장 큰 수를 뽑았을 때 가장 큰 수의 열.
static int preRow = -1;
//자유롭게 선택 가능한지 여부(전 행에 최댓값이 여러개 존재하면 다음 행은 자유롭게 선택 가능)
static boolean free = true;
//행에서 최댓값을 찾아줄 변수.
public int Search(int[] arr, int Row) {
int max = 0;
int temp = 0;
// System.out.println("이전 열은 : " + preRow);
if(free == true) {
for(int i=0; i<4; i++) {
if(arr[i] == max) {
free = true;
}
else if(arr[i] > max) {
max = arr[i];
free = false;
temp = i;
}
}
}
else {
for(int i=0; i<4; i++) {
if(arr[i] == max) {
free = true;
}
if(arr[i] > max && preRow != i) {
max = arr[i];
temp = i;
// System.out.print(max + " ");
// System.out.println();
}
}
}
preRow = temp;
return max;
}
int solution(int[][] land) {
int answer = 0;
for(int i=0; i<land.length; i++) {
// System.out.println("자유롭게 선택 가능한가 : " + free);
answer += Search(land[i], preRow);
// System.out.println(answer);
}
return answer;
}
}
[ 다른 사람의 풀이를 보고 푼 코드 ]
import java.util.Arrays;
class Solution {
int solution(int[][] land) {
int answer = 0;
for(int i=1; i<land.length; i++) {
land[i][0] += Math.max(Math.max(land[i-1][1], land[i-1][2]), land[i-1][3]);
land[i][1] += Math.max(Math.max(land[i-1][0], land[i-1][2]), land[i-1][3]);
land[i][2] += Math.max(Math.max(land[i-1][0], land[i-1][1]), land[i-1][3]);
land[i][3] += Math.max(Math.max(land[i-1][0], land[i-1][1]), land[i-1][2]);
}
int[] temp = land[land.length - 1];
Arrays.sort(temp);
answer = temp[temp.length - 1];
return answer;
}
}