9184 신나는 함수 실행

정민용·2023년 2월 19일

백준

목록 보기
71/286

문제

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

다음과 같은 재귀함수 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)를 출력하는 프로그램을 작성하시오.

import sys

input = lambda: sys.stdin.readline().strip()

def w(a, b, c):
  da, db, dc = a+50, b+50, c+50
  if a <= 0 or b <= 0 or c <= 0:
    d[da][db][dc] = 1
    
  elif a > 20 or b > 20 or c > 20:
    if d[70][70][70] != 10**7:
      d[da][db][dc] = d[70][70][70]
    else:
      d[da][db][dc] = w(20, 20, 20)
      
  elif a < b < c:
    if d[da][db][dc-1] == 10**7:
      d[da][db][dc-1] = w(a, b, c-1)
    if d[da][db-1][dc-1] == 10**7:
      d[da][db-1][dc-1] = w(a, b-1, c-1)
    if d[da][db-1][dc] == 10**7:
      d[da][db-1][dc] = w(a, b-1, c)
    d[da][db][dc] = d[da][db][dc-1] + d[da][db-1][dc-1] - d[da][db-1][dc]
    
  else:
    if d[da-1][db][dc] == 10**7:
      d[da-1][db][dc] = w(a-1, b, c)
    if d[da-1][db-1][dc] == 10**7:
      d[da-1][db-1][dc] = w(a-1, b-1, c)
    if d[da-1][db][dc-1] == 10**7:
      d[da-1][db][dc-1] = w(a-1, b, c-1)
    if d[da-1][db-1][dc-1] == 10**7:
      d[da-1][db-1][dc-1] = w(a-1, b-1, c-1)
    d[da][db][dc] = d[da-1][db][dc] + d[da-1][db-1][dc] + d[da-1][db][dc-1] - d[da-1][db-1][dc-1]

  return d[da][db][dc]

a, b, c = map(int, input().split())
d = [[[10**7] * 101 for _ in range(101)] for _ in range(101)]
while True:
  if a == -1 and b == -1 and c == -1:
    break
  w(a, b, c)
  number = d[a+50][b+50][c+50]
  print("w({}, {}, {}) = {}".format(a, b, c, number))
  a, b, c = map(int, input().split())

백준 9184 신나는 함수 실행

0개의 댓글