技术问询:求解构建两个重量均不小于k的袋子所需的最少物品数量及递归实现疑问
嘿,我完全理解你的困惑!单个袋子的递归思路确实很直观,但要同时处理两个不相交的袋子,还要追踪已使用的物品,确实会多一层复杂度。咱们一步步拆解这个问题,找到可行的解决方案。
问题核心梳理
我们的目标是选出两个不重叠的物品子集,每个子集的总重量至少为k,要让两个子集的物品总数尽可能小。如果不存在这样的子集,返回-1。
解法思路:从单袋到双袋的递归扩展
你之前用递归解决单袋问题时,只需要追踪当前袋子的重量和处理到的物品索引。现在要处理双袋,我们可以扩展递归的状态,同时记录两个袋子的当前重量,以及已经使用的物品数量,这样就能避免重复使用物品了。
1. 带状态的递归(记忆化优化)
递归状态定义
我们的递归函数需要追踪四个参数:
index:当前处理到第几个物品(从0开始计数)bag1:第一个袋子的当前总重量bag2:第二个袋子的当前总重量count:已经放入两个袋子的物品总数
递归逻辑
对于每个物品,我们有三种选择:
- 不放任何袋子:直接递归处理下一个物品,袋子重量和计数都不变
- 放入第一个袋子:如果第一个袋子还没达到
k(已经达到的话再放只会浪费物品),就把当前物品加入第一个袋子,计数+1,递归处理下一个物品 - 放入第二个袋子:同理,只有当第二个袋子未达标时才考虑放入,计数+1后递归处理下一个物品
终止条件
- 如果两个袋子的重量都≥
k:记录当前的count,作为候选的最小物品数 - 如果已经遍历完所有物品:这条路径不可行,直接返回
剪枝优化
为了避免不必要的递归计算,我们可以在递归过程中加入剪枝:如果当前的count已经大于等于我们已经找到的最小物品数,就直接终止这条路径的递归——毕竟继续下去也不可能得到更优的结果。
代码示例(Python)
import sys from functools import lru_cache def min_items_for_two_bags(k, weights): total_sum = sum(weights) # 提前排除不可能的情况:总重量不够2k,直接返回-1 if total_sum < 2 * k: return -1 n = len(weights) min_total = sys.maxsize # 记忆化缓存,避免重复计算相同状态 @lru_cache(maxsize=None) def dfs(index, bag1, bag2, count): nonlocal min_total # 剪枝:当前计数已经不优于已知最小值,直接返回 if count >= min_total: return # 满足条件,更新最小计数 if bag1 >= k and bag2 >= k: min_total = min(min_total, count) return # 遍历完所有物品,结束递归 if index == n: return # 选择1:不放当前物品 dfs(index + 1, bag1, bag2, count) # 选择2:放入第一个袋子(仅当袋子未达标时) if bag1 < k: dfs(index + 1, bag1 + weights[index], bag2, count + 1) # 选择3:放入第二个袋子(仅当袋子未达标时) if bag2 < k: dfs(index + 1, bag1, bag2 + weights[index], count + 1) dfs(0, 0, 0, 0) return min_total if min_total != sys.maxsize else -1 # 测试用例1 print(min_items_for_two_bags(4, [10])) # 输出:-1 # 测试用例2 print(min_items_for_two_bags(2, [2,2,2])) # 输出:2
2. 动态规划优化(适合较大物品数量)
如果物品数量N较大,递归可能会遇到栈溢出或效率问题,这时候可以用动态规划来优化。我们可以把状态压缩为dp[i][a][b],表示前i个物品中,第一个袋子重量为a、第二个袋子重量为b时的最小物品数。
为了压缩空间,我们可以把a和b的上限设为k——毕竟超过k的重量和刚好等于k的效果是一样的(都满足袋子的重量要求),这样能大幅减少状态数量。
边界情况处理
除了代码里的总重量检查,还要注意一些特殊情况:
- 所有物品都大于
k但数量不足2:比如k=4,物品[10],虽然总重量≥2k,但只有一个物品,无法分给两个袋子,返回-1 - 单个物品就能满足一个袋子,但剩余物品无法凑够另一个袋子:比如
k=5,物品[6,2,2],总重量10≥10,但剩余两个2的总和是4<5,所以返回-1
内容的提问来源于stack exchange,提问作者Dhairya Tripathi
相关产品推荐
相关产品推荐

