小M的能力选择挑战| 豆包MarsCode AI 刷题

119 阅读2分钟

问题描述

小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)