英雄升级与奖励最大化
问题描述
在一个游戏中,小W拥有 n 个英雄,每个英雄的初始能力值均为 1。她可以通过升级操作来提升英雄的能力值,最多可以进行 k 次升级。
每次升级操作包含以下步骤:
-
选择一个英雄
-
选择一个正整数
x -
将该英雄的能力值 𝑎𝑖ai 更新为:𝑎𝑖=𝑎𝑖+⌊𝑎𝑖/𝑥⌋ai=ai+⌊ai/x⌋
- 其中
⌊ ⌋表示向下取整操作
- 其中
游戏规则:
- 当英雄的能力值首次达到或超过目标值 𝑏𝑖bi 时,小W可以获得对应的奖励 𝑐𝑖ci
- 每个英雄的奖励只能获得一次
- 升级操作的选择是自由的,可以多次选择同一个英雄进行升级
请计算在最多进行 k 次升级操作后,小W能获得的最大奖励总和。
测试样例
样例1:
输入:
n = 4 ,k = 4 ,b = [1, 7, 5, 2] ,c = [2, 6, 5, 2]
输出:9
解释:可以通过以下操作获得最大奖励:
- 第一个英雄初始值为 1,已达到目标值 1,直接获得奖励2
- 第四个英雄初始值为 1,选择 x=1 升级一次变为 2,达到目标值2,获得奖励2
- 第三个英雄通过三次合理的升级操作 (1->2->4->5) 可达到目标值5,获得奖励5
总奖励为:2 + 2 + 5 = 9
样例2:
输入:
n = 3 ,k = 0 ,b = [3, 5, 2] ,c = [5, 4, 7]
输出:0
解释:无法进行升级操作,因此无法获得奖励
样例3:
输入:
n = 3 ,k = 3 ,b = [3, 5, 2] ,c = [5, 4, 7]
输出:12
解释:可以通过以下操作获得最大奖励:
可以通过合理的升级操作使第一个和第三个英雄达到目标值,获得总奖励5 + 7 = 12
解题思路
题目答案有问题,但题是好题,使用一个二维数组 dp,其中 dp[i][j] 表示在前 i 个英雄中,使用 j 次升级操作能获得的最大奖励。
英雄和升级条件是对应的。
遍历英雄,决定是否升级,不升级某个英雄的时候,dp[i][j] = dp[i][j] 升级的时候,所有比当前值大的都可以获得。
代码
def solution(n, k, b, c):
# 初始化dp数组,dp[i][j]表示在前i个英雄中,使用j次升级操作能获得的最大奖励
dp = [[0] * (k + 1) for _ in range(n + 1)]
# 遍历每个英雄
for i in range(1, n + 1):
# 计算从当前能力值到目标值所需的最小升级次数
# 这里需要一个辅助函数来计算最小升级次数
min_upgrades = calculate_min_upgrades(b[i-1])
# 遍历可用的升级次数
for j in range(k + 1):
# 不升级当前英雄的情况
dp[i][j] = dp[i-1][j]
# 尝试升级当前英雄,更新dp数组
for u in range(min_upgrades, j + 1):
# 更新dp[i][j],尝试使用u次升级操作,u是能完成升级操作的步骤
# dp[i-1][j-u]是我没用这么多步进行升级的前面的
dp[i][j] = max(dp[i][j], dp[i-1][j-u] + c[i-1])
# 返回最大奖励
return dp[n][k]
# 辅助函数:计算从当前能力值到目标值所需的最小升级次数
def calculate_min_upgrades(target):
# 初始能力值为1
current_value = 1
upgrades = 0
# 逐步增加能力值,直到达到或超过目标值
while current_value < target:
# 选择一个合适的x值,使得升级后的能力值尽可能接近目标值
x = 1 # 这里可以优化选择x的策略,但为了简单起见,我们先选择x=1
current_value += current_value // x
upgrades += 1
return upgrades
if __name__ == "__main__":
# Add your test cases here
print(solution(4, 4, [1, 7, 5, 2], [2, 6, 5, 2]) == 9)
print(solution(3, 0, [3, 5, 2], [5, 4, 7]) == 0)