동적계획법 (Dynamic Programming) - N으로 표현** (Lv.3)
2022. 3. 4. 15:57ㆍ2022/Programmers
문제 설명
아래와 같이 5와 사칙연산만으로 12를 표현할 수 있습니다.
12 = 5 + 5 + (5 / 5) + (5 / 5)
12 = 55 / 5 + 5 / 5
12 = (55 + 5) / 5
5를 사용한 횟수는 각각 6,5,4 입니다. 그리고 이중 가장 작은 경우는 4입니다.
이처럼 숫자 N과 number가 주어질 때, N과 사칙연산만 사용해서 표현 할 수 있는 방법 중 N 사용횟수의 최솟값을 return 하도록 solution 함수를 작성하세요.
제한사항
- N은 1 이상 9 이하입니다.
- number는 1 이상 32,000 이하입니다.
- 수식에는 괄호와 사칙연산만 가능하며 나누기 연산에서 나머지는 무시합니다.
- 최솟값이 8보다 크면 -1을 return 합니다.
입출력 예
N | number | return |
5 | 12 | 4 |
2 | 11 | 3 |
입출력 예 설명
예제 #1
문제에 나온 예와 같습니다.
예제 #2
11 = 22 / 2와 같이 2를 3번만 사용하여 표현할 수 있습니다.
동적계획법
동적 계획법의 접근 방식은 기본적으로 분할 정복 알고리즘과 비슷한 것으로 주어진 문제를 부분 문제로 나누어 각 부분 문제의 답을 계산하고, 이 계산한 결과값을 이용해 원래 문제의 답을 산출하기 때문이다. 여기서 분할정복과 차이가 생기는 부분은 원래의 문제를 부분 문제로 나누는 방식에 있다. 동적 계획법의 경우 주어진 문제를 나눌 때 부분 문제를 최대한 많이 이용하도록 나눈 다음, 주어진 부분 문제의 정답을 한 번만 계산하고 저장해둔 뒤 다시 한 번 이 부분 문제를 이용할 때에는 저장해둔 정답을 바로 산출하여 이용함으로써 속도를 향상시킨다.
위의 문제에 따르면, N = 5인 경우 아래와 같다.
'5' * 1 | 5 |
'5' * 2 | 55, 10, 0, 25, 1 |
그리고 3은 5 와 55로 표현 가능하다.
'5' * 3 | 555, 60, -50, 275, 15, -5, 50, 0, 5, 30, -20, 125, 6, 4, 2 |
즉, 가장 '5' * i는 '5'*x 와 '5'*(i-x)로 표현 가능하다.
이를 이용해서 문제를 풀어보았다.
def solution(N, number):
answer = [set([int(str(N)*i)]) for i in range(1, 9)]
# 예를 들어 N = 5, number = 5인 경우, 5 하나로 표현 가능하므로, return 1
if N == number :
return 1
# N을 사용한 횟수의 최솟값이 8 이상이면 -1 return
# answer[0]의 경우에는 {N} 한가지 경우밖에 없으므로 1부터 시작 & 인덱스는 0부터 시작하므로 8회가 answer[7]
for i in range(1, 8) :
# answer[i]
for j in range(i) :
for y in answer[j]:
for x in answer[i-j-1] :
answer[i].add(y+x)
answer[i].add(y*x)
answer[i].add(y-x)
if y > 0 :
answer[i].add(x//y)
if number in answer[i] :
return i+1
return -1
'2022 > Programmers' 카테고리의 다른 글
깊이/너비 우선 탐색(DFS/BFS) - 타겟넘버 (Lv.2) (0) | 2022.03.06 |
---|---|
동적계획법 (Dynamic Programming) - 정수 삼각형 (Lv.3) (0) | 2022.03.05 |
Hash - 위장 (LV.2) (0) | 2022.03.03 |
Hash - 완주하지 못한 선수 (Lv.1) (0) | 2022.03.02 |
Stack/Queue - 주식가격 (Lv.2) (0) | 2022.03.01 |