나의 풀이
def solution(money):
# 방법1. 맨 뒷 집을 제외한 경우
dp1 = [0]*len(money)
dp1[0] = money[0]
dp1[1] = max(money[0], money[1]) # 0,1번 집 중 더 돈이 많은 집 하나만 털 수 있음
for i in range(2,len(money)) :
if i != len(money) - 1 :
dp1[i] = max(dp1[i-2]+money[i], dp1[i-1])
else :
dp1[i] = max(dp1[i-2]+0, dp1[i-1]) # 마지막집이 없다고 가정했으므로 dp[i] 는 i-2, i-1 중 더 큰 값이 된다.
# 방법2. 맨 앞 집을 제외한 경우
dp2 = [0]*len(money)
dp2[0] = 0 # 맨 앞집을 0으로 두어 제외함
dp2[1] = money[1]
for i in range(2, len(money)) :
dp2[i] = max(dp2[i-2]+money[i], dp2[i-1])
return max(dp1[len(money)-1],dp2[len(money)-1])
- 마을의 집은 원형으로 이루어져있기 때문에, 첫번째집을 제외하고 문제를 푼 결과 / 마지막집을 제외하고 문제를 푼 결과 둘 중 더 큰 값을 정답으로 채택하는 것이 이 문제의 핵심이다.
- dp[i] 는 0~i 까지 집들을 선택하면서 훔친 돈의 최댓값을 뜻한다.
- 따라서 dp[i] = max(dp[i-2]+money[i], dp[i-1]) 라는 점화식을 도출해낼 수 있다.
- i-2까지의 최댓값 + i번째집을 털었을 때 vs i-1까지의 최댓값 중 더 큰 값이 dp[i] 이 되기 때문이다.
예) money = [10, 2, 2, 100, 2] 가 주어졌다고 가정해보자.
- 10과 2는 동시에 선택될 수 없기 때문에 10,2,2,100,0 / 0,2,2,100,2 라는 서로 다른 마을이 있다고 생각하고 문제를 풀어야 한다.
- 마지막집을 배제한 경우 : 10,2,2,100,0
- dp[0] = 10 / 선택된 집 : 0
- dp[1] = max(10,2) = 10 / 선택된 집 : 0
- dp[2] = max(10+2, 10) = 12 / 선택된 집 : 0, 2
- dp[3] = max(10+100, 12) = 110 / 선택된 집 : 0, 3
- dp[4] = max(12,110) = 110 / 최종선택된 집 : 0, 3
- 첫번째집을 배제한 경우 : 0,2,2,100,2
- dp[0] = 0 / 선택된 집 : 0
- dp[1] = max(0,2) = 2 / 선택된 집 : 1
- dp[2] = max(0+2, 2) = 2 / 선택된 집 : 0,2 or 1
- dp[3] = max(2+100, 2) = 102 / 선택된 집 : 1,3
- dp[4] = max(2+2, 102) = 102 / 최종선택된 집 : 1,3
- 마지막집을 배제한 경우 : 110 , 첫번째집을 배제한 경우 : 102 -> 더 큰 값 110
'알고리즘 > 동적프로그래밍(DP)' 카테고리의 다른 글
[백준] 1932번: 정수 삼각형 - 파이썬(python) (0) | 2022.10.19 |
---|---|
[프로그래머스] 사칙연산 - 파이썬(python) (0) | 2022.09.20 |
[프로그래머스] 등굣길 - 파이썬(python) (0) | 2022.09.19 |
[프로그래머스] 정수 삼각형 - 파이썬(python) (0) | 2022.09.17 |
[프로그래머스] N으로 표현 - 파이썬(python) (0) | 2022.09.17 |
댓글