다음의 점화식에 의해 정의된 수열 t(n)을 생각하자:
첫째 줄에 n (0 ≤ n ≤ 35)이 주어진다.
첫째 줄에 t(n)을 출력한다.
3
5
25
4861946401452
점화식하면 DP죠😎
DP를 사용하면 해결할 수 있는 문제입니다.
저는 점화식에서 다음과 같은 규칙을 발견했습니다.
이 짝수일 경우, 위의 수식과 같이 같은 값이 두 번씩 반복되는 것을 찾아볼 수 있습니다.
이 홀수일 경우, 짝수인 경우와 똑같지만, 파란색 부분이 추가적으로 계산되는 것을 찾아볼 수 있습니다.
따라서, DP를 사용하면서 위와 같은 규칙을 통해 절반만 계산하고 값을 두 배하는 방식으로 문제를 해결하였습니다.
반복문을 이용한 bottom up 방식의 DP 코드입니다.
import sys
n = int(sys.stdin.readline())
dp = [1] + ([0] * (n)) # dp[n]에는 T(n)의 값이 저장, dp[0]은 1
for i in range(1, n + 1): # T(1)부터 T(n)까지 계산
for j in range(i // 2): # 절반 계산
dp[i] += dp[j] * dp[i - j - 1]
dp[i] *= 2 # 계산값 두 배
if i % 2 == 1: dp[i] += dp[i // 2] * dp[i // 2] # 홀수인 경우 추가 계산
print(dp[n])
재귀 함수를 이용한 top down 방식의 DP 코드입니다.
import sys
n = int(sys.stdin.readline())
dp = [1] + ([0] * (n))
def top_down(n):
if dp[n] != 0: return dp[n] # 이미 계산된 값이라면 해당 값 return
for i in range(n // 2):
dp[n] += top_down(i) * top_down(n - i - 1)
dp[n] *= 2
if n % 2 == 1: dp[n] += top_down(n // 2) * top_down(n // 2)
return dp[n]
print(top_down(n))