- 题目: 小F正在设计一款手游,游戏中的角色战力值需要根据一定规则来平衡,以提升玩家的游戏体验。现在游戏中有 n 个角色,编号从 0 到 n-1。为了保证平衡性,角色战力值需要遵循以下规则: 编号为 0 的角色战力值初始为 0。 每个角色的战力值必须是非负整数。 相邻角色的战力值差不能超过 1,即两个相邻角色的战力值差可以是 0、+1 或 -1。 除此之外,游戏策划还为某些角色设定了最大战力值。这些限制通过若干数对给出,每一个数对 limit[i] = [index, maxPower],表示编号为 index 的角色的战力值不能超过 maxPower。这些限定只会对编号不为 0 的角色生效。 你的任务是根据上述规则和限制,计算游戏中单个角色能达到的最大战力值。
- 解题思路:
- 我们可以使用动态规划的思想来解决这个问题。从编号为0的角色开始,逐步计算每个角色在满足所有规则和限制条件下能达到的最大战力值。
- 首先,初始化一个长度为 n 的列表 dp ,用于存储每个角色的最大战力值。由于编号为0的角色战力值初始为0,所以 dp[0] = 0 。
- 然后,对于每个角色 i (从1到 n - 1 ),我们考虑它的战力值可能的取值范围。因为相邻角色的战力值差不能超过1,所以角色 i 的战力值 dp[i] 应该在 dp[i - 1] - 1 到 dp[i - 1] + 1 这个区间内。
- 同时,我们还要考虑游戏策划为某些角色设定的最大战力值限制。如果存在限制 limit[j] = [index, maxPower] 且 index == i ,那么 dp[i] 不能超过 maxPower 。
- 在计算每个角色的最大战力值时,我们取上述条件下的最大值作为 dp[i] 的值。
- 最后,遍历完所有角色后, dp 列表中存储的就是每个角色在满足所有规则和限制下能达到的最大战力值,我们可以返回整个 dp 列表或者根据需求返回特定角色的最大战力值。
- 示例图示(以简单示例说明动态规划过程):
假设我们有 n = 5 个角色,并且有一个限制 limit = [[2, 2]] ,表示编号为2的角色战力值不能超过2。
- 初始化:创建 dp 列表, dp[0] = 0 。
角色编号 0 1 2 3 4 dp值 0
- 计算角色1的战力值:因为相邻角色战力值差不能超过1,且角色0的战力值为0,所以角色1的战力值 dp[1] 可以是 dp[0] - 1 到 dp[0] + 1 ,即 0 - 1 到 0 + 1 ,也就是 [-1, 1] 。由于战力值必须是非负整数,所以 dp[1] = 1 。
角色编号 0 1 2 3 4 dp值 0 1
- 计算角色2的战力值: dp[2] 应该在 dp[1] - 1 到 dp[1] + 1 ,即 1 - 1 到 1 + 1 ,也就是 [0, 2] 。但由于有 limit 限制,编号为2的角色战力值不能超过2,所以 dp[2] = 2 。
角色编号 0 1 2 3 4 dp值 0 1 2
- 计算角色3的战力值: dp[3] 在 dp[2] - 1 到 dp[2] + 1 ,即 2 - 1 到 2 + 1 ,也就是 [1, 3] ,取最大值且满足非负整数条件, dp[3] = 3 。
角色编号 0 1 2 3 4 dp值 0 1 2 3
- 计算角色4的战力值: dp[4] 在 dp[3] - 1 到 dp[3] + 1 ,即 3 - 1 到 3 + 1 ,也就是 [2, 4] ,取最大值且满足非负整数条件, dp[4] = 4 。
角色编号 0 1 2 3 4 dp值 0 1 2 3 4
Python代码如下:
`from typing import List
def maxPower(n: int, limit: List[List[int]]) -> List[int]: dp = [0] * n for i in range(1, n): prev_power = dp[i - 1] min_power = max(0, prev_power - 1) max_power = prev_power + 1
for index, maxPower in limit:
if index == i:
max_power = min(max_power, maxPower)
dp[i] = max(min_power, max_power)
return dp`
代码详解:
- maxPower 函数接受两个参数: n 表示角色的数量, limit 表示游戏策划为某些角色设定的最大战力值限制的列表,其中每个元素是一个包含角色编号和最大战力值的列表。
- 首先,我们初始化 dp 列表,将 dp[0] 设置为0,这是根据编号为0的角色战力值初始为0的规则。
- 然后,我们使用一个循环遍历从1到 n - 1 的每个角色编号 i 。
- 对于每个角色 i ,我们先获取前一个角色 i - 1 的战力值 prev_power ,根据相邻角色战力值差不能超过1的规则,计算出角色 i 的战力值的可能取值范围的下限 min_power 和上限 max_power 。下限 min_power 通过取 prev_power - 1 和0中的最大值来确保战力值是非负整数。上限 max_power 则是 prev_power + 1 。
- 接着,我们遍历 limit 列表中的每个限制条件。如果某个限制条件中的角色编号 index 等于当前角色编号 i ,那么我们就更新 max_power ,使其不超过该限制条件中的最大战力值 maxPower 。
- 最后,我们取 min_power 和 max_power 中的最大值作为角色 i 的战力值 dp[i] ,并将其存储到 dp 列表中。
- 当循环结束后, dp 列表中存储的就是每个角色在满足所有规则和限制条件下能达到的最大战力值,我们将其返回作为函数的结果。