-
[프로그래머스] 도둑질 (파이썬)알고리즘 2022. 2. 2. 16:11
문제 링크
https://programmers.co.kr/learn/courses/30/lessons/42897
코딩테스트 연습 - 도둑질
도둑이 어느 마을을 털 계획을 하고 있습니다. 이 마을의 모든 집들은 아래 그림과 같이 동그랗게 배치되어 있습니다. 각 집들은 서로 인접한 집들과 방범장치가 연결되어 있기 때문에 인접한
programmers.co.kr
문제풀이
원을 따라 위치한 집들을 털 때, 최대로 훔칠 수 있는 값을 리턴하는 문제이다.
이 문제에서는 기준점을 정해주는 것이 풀이의 첫단추를 꿰는 것이다.
나는 1번 째 집을 기준점으로 정했고,
1번째 집을 터는 경우와 털지 않는 경우 두 가지로 나누어서, 두 케이스 중 최댓값을 리턴하는 식으로 진행했다.
그리고 1번째 집부터 n 번째 집까지 순서대로 턴다고 가정하고, 각 단계에서 최대로 많이 털 수 있는 값을 가져오는 식으로 dp 를 짰다.
1번 째 집을 터는 경우엔, 마지막 집과 2번째 집을 털지 못하므로, dp[2] 와 dp[n] 은 0 이다.
dp[3] 은 자연스럽게 dp[1] + v[3] 이 되며, dp[1], dp[2], dp[3] 의 값을 구했으므로 점화식을 이용하여 풀면된다.
점화식은
dp[k] = v[k] + max(dp[k-2], dp[k-3]) 으로 구할 수 있다.
1번째 집을 털지 않는 경우엔,
dp[1] = 0 이고, dp[2] 는 v[2], dp[3] 은 v[3] 으로 정할 수 있다.
이 경우에도 첫번째 경우와 마찬가지로 점화식을 적용해서 풀면된다.
시간복잡도
집의 최대 개수는 1,000,000 이다.
dp[k] 를 채우기 위해서 dp[k-2], dp[k-3] 을 비교하면 되므로
시간 복잡도는 2 * n 즉, O(N) 이다.
소스코드
def solution(money): case1 = [0] * len(money); case2 = [0] * len(money); # 0번째 집을 털경우 case1 case1[0] = money[0]; case1[1] = 0; case1[2] = case1[0] + money[2]; for i in range(3, len(money)): case1[i] = money[i] + max(case1[i - 2], case1[i - 3]); case1[len(money) - 1] = 0; # 0번째 집을 털지 않을 경우 case2 case2[0] = 0; case2[1] = money[1]; case2[2] = money[2]; for j in range(3, len(money)): case2[j] = money[j] + max(case2[j - 2], case2[j - 3]); answer = max(max(case1), max(case2)); return answer
'알고리즘' 카테고리의 다른 글
[프로그래머스] 네트워크 (파이썬) (0) 2022.02.03 [프로그래머스] 타겟넘버 (파이썬) (0) 2022.02.03 [프로그래머스] 정수 삼각형 (파이썬) (0) 2022.02.02 [프로그래머스] N으로 표현 (파이썬) (0) 2022.02.02 100일 동안 매일 알고리즘을 하면? - 14일차 (0) 2022.01.20