我正在尝试从 Code Jam 的 2021 年资格赛中为Moons 和 Umbrellas提出 DP 解决方案。以下是我的工作递归解决方案,基于他们的分析:
import sys
from functools import lru_cache
sys.setrecursionlimit(5000)
T = int(input())
for case in range(1, T+1):
X, Y, S = input().split()
X = int(X)
Y = int(Y)
S = tuple(S)
@lru_cache(maxsize=128)
def cost(S):
if len(S) <= 1:
return 0
if S[0] == '?':
return min(cost(('C',) + S[1:]), cost(('J',) + S[1:]))
if S[0] != '?' and S[1] == '?':
return min(cost((S[0],) + ('C',) + S[2:]), cost((S[0],) + ('J',) + S[2:]))
if S[0] == S[1]:
return cost(S[1:])
if S[0] == 'C' and S[1] == 'J':
return X + cost(S[1:])
if S[0] == 'J' and S[1] == 'C':
return Y + cost(S[1:])
print(f'Case #{case}: {cost(S)}')
简而言之,问题是给定一串C
's、J
's 和?
s(例如CCJCJ??JC
or JCCC??CJ
),问号应替换为C
or J
。最小化从C
到转换的成本,J
反之亦然。这两种类型的转换具有不同的成本。
如何使用自下而上的方法将其转换为 DP 解决方案?