题解 | 魔理沙的魔导书收纳

魔理沙的魔导书收纳

https://www.nowcoder.com/practice/3d3edae90afe4fa8bb2db15f314a9b88

REALHW163 魔理沙的魔导书收纳

解题思路

这道题是反悔贪心 / DP 问题,核心难点在于:题目要求按顺序处理(不能重排),且挑战条件是当前魔力严格大于消耗值。

用 DP 求解:dp[i][k] 表示前 i 本书中成功挑战了 k 本时,能剩余的最大魔力值。值为 -1 表示该状态不可达。

状态转移:

  • 跳过第 i 本dp[i][k] = dp[i-1][k]
  • 挑战第 i 本(需要 dp[i-1][k-1] > a[i-1]):dp[i][k] = max(dp[i][k], dp[i-1][k-1] - a[i-1] + b[i-1])

最终从大到小找最大的 k 使得 dp[n][k] >= 0

代码实现

e = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))
n = len(a)

dp = [[-1] * (n + 1) for _ in range(n + 1)]
dp[0][0] = e

for i in range(1, n + 1):
    for k in range(n + 1):
        dp[i][k] = dp[i - 1][k]
        if k > 0 and dp[i - 1][k - 1] > a[i - 1]:
            dp[i][k] = max(dp[i][k], dp[i - 1][k - 1] - a[i - 1] + b[i - 1])

for k in range(n, -1, -1):
    if dp[n][k] >= 0:
        print(k)
        break

代码解析

以示例 E=18, a=[15,17,4,18], b=[1,15,4,17] 为例:

dp[i][k] 的含义:处理完前 i 本书、挑战了 k 本时,剩余的最大魔力。

第 1 本书 (a=15, b=1):消耗大反馈少(净亏 14),跳过更优第 2 本书 (a=17, b=15):dp[0][0]=18 > 17,挑战后剩 18-17+15=16第 3 本书 (a=4, b=4):dp[2][1]=16 > 4,挑战后剩 16-4+4=16第 4 本书 (a=18, b=17):dp[3][2]=16 ≯ 18,无法挑战

最终 dp[4][2]=16 >= 0dp[4][3]=-1,所以最多挑战 2 本。

为什么存最大剩余魔力而非能否到达:同样挑战 k 本,剩余魔力越多越好,因为后续挑战需要魔力严格大于消耗值。存最大值保证不遗漏可行解。

复杂度分析

  • 时间复杂度:O(n²),n ≤ 100,最多 10000 次运算
  • 空间复杂度:O(n²),可滚动数组优化到 O(n)
全部评论

相关推荐

评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务