algorithm - 子集总和变化:找到总和 >= 目标的子集,超调最小
问题描述
给定一组正整数和一个目标总和k,找到总和恰好为k或最小超过k的子集。(即相等或最小的过冲)
这个问题发生在现实生活中的业务功能请求中,预计集合大小通常在 1 到 30 之间。它必须可以在 3 秒内由低端 PC 解决,所以我猜测是蛮力方法可能无法处理超过 10 个输入整数?
我已经查看了与子集总和和背包相关的搜索命中,但还没有看到有人讨论这个 >= 变化。
解决方案
这是原始程序的一个相当简单的扩展:我们只使用动态规划算法,但如果这些超出原始值,我们也会生成存储列表。
例如,我们可以实现这样的算法:
def least_gt_subset_sum(items, k):
vals = [None]*(k+1)
vals[0] = ()
best_v = None
best_k = 0
for item in items:
for i in range(k-1, -1, -1):
if vals[i] is not None:
if i + item <= k and vals[i+item] is None:
vals[i+item] = (*vals[i], item)
if i + item > k and (best_v is None or i + item < best_v):
best_v = i + item
best_k = (*vals[i], item)
if vals[k] is not None:
return vals[k]
else:
return best_k
所以在这里我们使用相同的技巧,但是如果值高于k
,我们会做一些记账,并存储最好的结果。最后,我们看看是否有一个完全匹配的值,如果没有,我们返回更高的最佳集合,否则我们返回精确的那个。
推荐阅读
- html - 使用引导程序显示更多和更少的选项
- forms - 使用 Django REST 框架时如何克服 FormData 限制?
- c# - 强制 Kerberos 或 NTLM 登录到 Active Directory 域
- c# - 如何避免在我的数据库中出现重复数据?
- html - Angular2自定义工具提示图标点击
- node.js - 将中间件添加到单个路由 Js Express 的最简洁方法
- tensorflow.js - 分类器输出错误
- variables - Fortran 中的变量识别问题
- python - 在 Django 中间件中获取表单数据
- android - 基于其子元素的可扩展背景图像