问题描述
小M最近在玩一款叫做“狼人拯救者”的游戏。在游戏中,玩家可以通过消耗金币来购买能力,这些能力会增加攻击力,但也会影响攻击速度。
小M是一个以攻击力为优先的玩家,但他必须保证自己的攻击速度不能低于0,因为攻击速度为负时将无法攻击。
现在小M面对商店中的N种能力,他拥有G枚金币和S点初始攻击速度。他想知道,在保持攻击速度大于等于0的前提下,他最多可以获得多少攻击力。
商店中每种能力用三元组表示为 array[i] = [c, s, d],其中:
c表示购买该能力需要的金币数;s表示该能力对攻击速度的影响,可以为正数、零或负数;d表示该能力对攻击力的增加值。
思路
DFS + 记忆化搜索
初始算法
利用DFS回溯得到符合条件的每种金币+攻击+攻击力+攻击速度的组合。保存到结果数组中,求出攻击力最大值。
算法优化
利用哈希表将每种攻击速度+金币组合所得攻击力的结果加以存储,在每一次递归过程中,如果发现攻击速度+金币组合存在于哈希表中,并且小于该攻击力的值,就不再继续递归,达到时间上的优化。
代码实现
def solution(n, g, s, array):
# Edit your code here
# Initialize the result and visited array
res = [-float('inf')] # Store the maximum result (initially very small)
visited = [False] * n
memo = {}
# Define DFS with pruning and memoization
def dfs(c, spd, d):
if c < 0 or spd < 0:
return # Pruning: if resources or speed are exhausted, stop
if (c, spd) in memo and memo[(c, spd)] >= d:
return # If this state has already been visited with a better or equal result, stop
# Update the best result
res[0] = max(res[0], d)
# Mark the state as visited in the memo
memo[(c, spd)] = d
# Explore the next possibilities
for i in range(n):
if not visited[i]: # If this item hasn't been visited yet
visited[i] = True
# Recursively try the next item
dfs(c - array[i][0], spd + array[i][1], d + array[i][2])
visited[i] = False # Backtrack to explore other options
# Start DFS from the given resources and speed with initial score 0
dfs(g, s, 0)
return res[0]
if __name__ == "__main__":
# Add your test cases here
test1 = [
[71, 51, 150],
[40, 50, 100],
[40, 50, 100],
[30, 30, 70],
[30, 30, 70],
[30, 30, 70],
]
print(solution(6, 100, 100, test1) == 240)
test1 = [
[71, -51, 150],
[40, -50, 100],
[40, -50, 100],
[30, -30, 70],
[30, -30, 70],
[30, -30, 70],
]
print(solution(6, 100, 100, test1) == 210)