You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

竞赛编程:以最低成本通关所有关卡——未通过全部测试用例

嘿,我来帮你梳理这个问题的正确解法思路,你的问题属于典型的动态规划问题,尤其是状态压缩DP的范畴,咱们一步步来拆解:

问题本质先搞清楚

首先得明确题目规则的正确理解(我猜你可能在这里没踩准?):

你可以按任意顺序挑战关卡,但挑战某个关卡时,必须拥有该关卡要求的所有武器——如果有缺失的,必须一次性买齐这些缺失的武器,花费是新增武器数量的平方;武器买了之后就一直携带,后续挑战其他关卡可以重复使用。目标是通关所有关卡,总花费最小。

如果是这个规则,那核心就是找一个关卡挑战顺序,让每次新增武器的平方和最小。

两种可行的DP思路

思路一:以「已通关的关卡集合」为状态

适合关卡数量N较小的情况(比如N≤20,因为2^20≈1e6,计算量可控):

  • 状态定义:用二进制数U表示已通关的关卡集合(比如U的第i位为1表示关卡i已通关),dp[U]表示通关U中所有关卡的最小总花费。另外预处理一个数组mask[U],表示U中所有关卡要求的武器的并集(也就是通关这些关卡后你拥有的武器集合)。
  • 初始化:dp[0] = 0(没通关任何关卡,花费0),其他dp[U]初始化为无穷大;mask[0] = 0(没武器)。
  • 状态转移:遍历每个已通关集合U,再遍历所有未通关的关卡i:
    1. 计算新的通关集合U' = U | (1 << i)
    2. 计算这次需要新增的武器数量:x = __builtin_popcount( mask[U] ^ (mask[U] | S[i]) )(其实就是S[i]中不在mask[U]里的武器数量)
    3. 更新dp[U'] = min( dp[U'], dp[U] + x*x ),同时更新mask[U'] = mask[U] | S[i]
  • 最终答案:dp[(1<<N)-1](所有关卡都通关的状态)

思路二:以「已拥有的武器集合」为状态

适合武器种类M较小的情况(比如M≤20,2^20≈1e6):

  • 状态定义:用二进制数mask表示已拥有的武器集合,dp[mask]表示拥有这些武器的最小总花费。
  • 初始化:dp[0] = 0(没武器,花费0),其他dp[mask]初始化为无穷大。
  • 状态转移:遍历每个武器集合mask,再遍历所有关卡i:
    1. 计算新的武器集合new_mask = mask | S[i](挑战关卡i后,你会拥有所有该关卡要求的武器)
    2. 新增武器数量x = __builtin_popcount(new_mask) - __builtin_popcount(mask)
    3. 更新dp[new_mask] = min( dp[new_mask], dp[mask] + x*x )
  • 最终答案:dp[full_mask],其中full_mask是所有关卡要求的武器的并集(因为拥有这些武器后,你可以通关所有关卡,不需要额外花费)
为什么你的解法可能没过测试用例?

常见的坑点:

  1. 用了贪心算法:比如每次选当前新增武器最少的关卡,但贪心不一定最优!举个例子:关卡A要{0,1},关卡B要{2,3},关卡C要{0,2}。贪心先选A(花费4)再选B(花费4)总8,但最优是先选C(花费4),再选A(新增1件,花费1),再选B(新增1件,花费1),总6。
  2. 状态转移计算错误:比如把新增武器数量算成了S[i]的总大小,而不是S[i]中未拥有的数量。
  3. DP数组初始化问题:比如初始值设得不够大(比如用int而不是long long,虽然大部分情况int够,但保险起见用long long避免溢出),或者初始值没设为无穷大,导致错误的最小值。
  4. 状态遗漏:比如没遍历所有可能的状态,或者转移时漏掉了某些关卡。
代码实现小技巧
  • 预处理mask[U]可以用递推:mask[U] = mask[U ^ (1<<i)] | S[i],其中i是U中任意一个已通关的关卡,这样比每次计算并集快。
  • 计算二进制中1的数量,C++可以用__builtin_popcount(),Python可以用bin(mask).count('1')。
  • 如果N或M较大(比如N=25),可以考虑优化:比如用状态合并,对于相同武器集合的不同通关集合,只保留最小花费的那个,减少计算量。

内容的提问来源于stack exchange,提问作者John Stevens

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:50:39