알고리즘/알고리즘문제

동적계획법 - 백준 9184

Unipiz 2022. 7. 5. 10:02

백준 9184

동적계획법 - 신나는 함수 여행

문제

 

재귀 호출만 생각하면 신이 난다! 아닌가요?

다음과 같은 재귀함수 w(a, b, c)가 있다.

if a <= 0 or b <= 0 or c <= 0, then w(a, b, c) returns:
    1

if a > 20 or b > 20 or c > 20, then w(a, b, c) returns:
    w(20, 20, 20)

if a < b and b < c, then w(a, b, c) returns:
    w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c)

otherwise it returns:
    w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1)

위의 함수를 구현하는 것은 매우 쉽다. 하지만, 그대로 구현하면 값을 구하는데 매우 오랜 시간이 걸린다. (예를 들면, a=15, b=15, c=15)

a, b, c가 주어졌을 때, w(a, b, c)를 출력하는 프로그램을 작성하시오.

 

입력

 

입력은 세 정수 a, b, c로 이루어져 있으며, 한 줄에 하나씩 주어진다. 입력의 마지막은 -1 -1 -1로 나타내며, 세 정수가 모두 -1인 경우는 입력의 마지막을 제외하면 없다.

 

출력

 

입력으로 주어진 각각의 a, b, c에 대해서, w(a, b, c)를 출력한다.

 

제한

 

  • -50 ≤ a, b, c ≤ 50

 

접근.

점화식을 수도코드로 알려줘서 간단하게 캐시기능을 할 디피테이블만 사용하면 될 듯 싶었다.

허나 a,b,c가 -N 인 음수인 경우가 있어서 캐시를 3중 map 구조로 초기화하여 이용하기로 결정!

 

dp={}
for i in range(-50,51):
	dp[i]={}
	for j in range(-50,51):
		dp[i][j]={}
		for k in range(-50,51):
			dp[i][j][k]=51

def w_(a,b,c):
	if dp[a][b][c]!=51:
		return dp[a][b][c]
	if a <= 0 or b <= 0 or c <= 0:
		dp[a][b][c]=1
	elif a > 20 or b > 20 or c > 20:
		dp[a][b][c]=w_(20,20,20)
	elif a < b and b < c:
		dp[a][b][c]=w_(a,b,c-1)+w_(a,b-1,c-1)-w_(a,b-1,c)
	else:
		dp[a][b][c]=w_(a-1, b, c) + w_(a-1, b-1, c) + w_(a-1, b, c-1) - w_(a-1, b-1, c-1)
	return dp[a][b][c]

while True:
	N,M,K=map(int,input().split())
	if N==-1 and N==M and N==K:
		break
	print(f"w({N}, {M}, {K}) = {w_(N,M,K)}")

 

>> 문제는 맞혔으나 다른 이들의 풀이를 찾아본 결과 그냥 0~20까지의 캐시테이블만을 사용하는 것을 보고,

     점화식이 주어졌다고 대충보지 말자는 결론.

 

추가공부 - 사용가능 메모리가작으면서 음수까지 있을 때는 어떻게 풀것인가 고민해보기.

'알고리즘 > 알고리즘문제' 카테고리의 다른 글

[알고리즘] 백준 2675 문자열 반복  (0) 2022.07.14
[알고리즘] 백준 1753 최단경로  (0) 2022.07.08
Map - 숫자 카드  (0) 2022.07.04
정렬 - 좌표 압축  (0) 2022.07.04
정렬 - 좌표 정렬하기  (0) 2022.07.03