신나는 함수 실행
대놓고 재귀를 dp로 만드는 문제.
그런데 아무리 생각해도 바보같이 풀었다.
먼저 처음 제출한 풀이
INF = int(1e9)
dp = [[[INF]*21 for _ in range(21)]for _ in range(21)]
def w(a,b,c):
if a <= 0 or b <= 0 or c <= 0:
return 1
if a > 20 or b > 20 or c > 20:
if dp[20][20][20] == INF:
dp[20][20][20] = w(20,20,20)
return dp[20][20][20]
if a < b and b < c:
if dp[a][b][c-1] == INF:
dp[a][b][c-1] = w(a,b,c-1)
if dp[a][b-1][c-1] == INF:
dp[a][b-1][c-1] = w(a,b-1,c-1)
if dp[a][b-1][c] == INF:
dp[a][b-1][c] = w(a,b-1,c)
return dp[a][b][c-1] + dp[a][b-1][c-1] - dp[a][b-1][c]
if dp[a-1][b][c] == INF:
dp[a-1][b][c] = w(a-1,b,c)
if dp[a-1][b-1][c] == INF:
dp[a-1][b-1][c] = w(a-1,b-1,c)
if dp[a-1][b][c-1] == INF:
dp[a-1][b][c-1] = w(a-1,b,c-1)
if dp[a-1][b-1][c-1] == INF:
dp[a-1][b-1][c-1] = w(a-1,b-1,c-1)
return dp[a-1][b][c] + dp[a-1][b-1][c] + dp[a-1][b][c-1] - dp[a-1][b-1][c-1]
while True:
a,b,c = map(int,input().split())
if a==-1 and b==-1 and c==-1:
break
print(f"w({a}, {b}, {c}) = {w(a,b,c)}")
딱 봐도 더럽다.
사실 이 풀이가 시간적인 측면에선 더 좋다. 왜냐면, 함수 콜을 할 지 말지 콜하기 전에 걸르는 코드이기 때문이다. 그러나 가독성이 너어어무 안좋고(실제로 오타남), 이렇게까지 시간을 아끼지 않아도 풀 수 있는 문제라 그냥 함수콜을 한 다음에 메모제이션이 되어 있으면 리턴하는 식으로 문제를 풀면 더 좋을 듯 하다.
그래서 (다른데서 보고)고친 코드
...
def w(a,b,c):
if a <= 0 or b <= 0 or c <= 0:
return 1
if a > 20 or b > 20 or c > 20:
return w(20,20,20)
//콜을 한 다음 메모제이션이 되어있는지 체크한다
if dp[a][b][c] != INF:
return dp[a][b][c]
//안돼있으면 메모제이션부터 하고, 저장된 값을 내보낸다
if a<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]
...