문제:
땅따먹기 (level 2).

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


[접근]

  1. 이전행의 max값 중복여부와 인덱스, 현재행의 max값 중복여부와 인덱스, 차상위 max값 선택이 필요한 경우 등을 기준으로 고려해야할 경우를 뽑음.
    • 두 행 모두 max값 중복보유 및 인덱스 겹침
    • 두 행 모두 max값 중복보유 및 인덱스 안 겹침
    • 이전행 max값 중복보유
    • 현재행 max값 중복보유
    • 이전행 차상위 max값 선택필요한 경우
    • 현재행 차상위 max값 선택필요한 경우
  2. if문 계속 달면서 규칙을 만들다가 내가 뭐하는 건지 멘붕옴.
  3. 어차피 이전행의 각 원소들을 다음행의 해당 원소의 인덱스를 제외한 max값을 더해주면 되는 거라는 거를 깨달음.
    • Dynamic Programming을 적용함.
    • 변수 cp에 land를 복사함.
    • 첫 for문에서 r행의 시작을 0번째 행이 아닌 1번째 행부터 시작하게함.
      • 대신, 변수 temp에 r-1 행을 복사함.
      • 두번째 for문에서, r행의 원소들을 업데이트함.
        • 기존 r행의 원소에, 이전행의 값을 가진 (앞에서 계속 업데이트된) temp에서, r행의 해당 원소와 같은 인덱스의 원소를 제외하고 최대값을 더해서 업데이트함.
    • 최종 업데이트된 cp의 마지막 줄에서 최대값을 return함.
def solution(land):
    cp = [[x for x in row] for row in land]

    for r in range(1,len(land)):
        temp = cp[r-1][:]
        for i in range(len(land[0])):
            cp[r][i] = cp[r][i] + max(temp[:i] + temp[i+1:])
    return max(cp[-1])
# test case
land = [[1,2,3,4],[8,8,3,2],[6,7,4,5],[1,3,5,7]]

cp = [[x for x in row] for row in land]
for r in range(1,len(land)):
    temp = cp[r-1][:]
    print(r,"번째")
    print(cp[r-1],cp[r])
    for i in range(len(land[0])):
        cp[r][i] = cp[r][i] + max(temp[:i] + temp[i+1:])
    print(cp[r])
    print()
print('최종: ', end='')
print(cp)

solution(land)
1 번째
[1, 2, 3, 4] [8, 8, 3, 2]
[12, 12, 7, 5]

2 번째
[12, 12, 7, 5] [6, 7, 4, 5]
[18, 19, 16, 17]

3 번째
[18, 19, 16, 17] [1, 3, 5, 7]
[20, 21, 24, 26]

최종: [[1, 2, 3, 4], [12, 12, 7, 5], [18, 19, 16, 17], [20, 21, 24, 26]]





26

문제 출처

  • https://programmers.co.kr/learn/courses/30/lessons/12913