首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果组的和至少为K,则从数组中选择元素的方法数

如果组的和至少为K,则从数组中选择元素的方法数
EN

Stack Overflow用户
提问于 2017-03-02 11:45:04
回答 1查看 1.5K关注 0票数 0

问题:如果我们给出整数N,K和N大小的数组,例如1 <= N <= 36,数组中的每一个整数都是<=10^13。现在我们必须考虑从数组中提取元素的不同方法,使这些元素的和至少是K。

这里有一个例子:n= 4,K=6,array = {1,2,5,4}答案是9,因为我们可以用九种不同的方式从数组中提取元素,它们的和至少是K,答案是元素(第一和第三);(第二和第三);(第一、第二和第三);(第二和第四);(第一、第二和第四);(第一、第三和第四);(第二、第三和第四);(第一、第二、第三和第四);(第三和第四)。

我的想法是,使用位掩码,我们可以搜索所有的组合,并选择我们应该采取还是不应该,但这有O(2^N)的复杂性,在我们的例子中,N <=36太慢。

EN

回答 1

Stack Overflow用户

发布于 2017-03-02 15:58:55

对于这个问题,您可以使用类似于通常用于在时间O(N*2^(N/2))中解决子集和问题的“中间技巧”(meet in the中间技巧)(并且您将具有相同的复杂性)。

首先,计算第一个2^N/2元素的可能和,并存储它们。对最后一个N/2元素也做同样的操作。

现在,两种排序都是按递增顺序排列的。对n元素进行排序需要时间( O(n log n) ),因此这里需要O(N 2^(N/2))成本。让我们调用这两个排序集FL (对于第一个和最后一个)。

然后,执行以下操作:

设res =0 对于I从0到2^(N/2)-1{ 在{0,..,2^(N/2)-1}中找到最小的..,2^,使Fi + Lj_i >= K(对此使用二次搜索) 如果存在这样的j_i,则将res增加(2^(N/2) - j_i) } 返回区域

这样做的想法是,对于第一个N/2元素的每个子集,您将看到有多少种方法可以选择最后一个N/2元素的子集,以使总和高于K。为此,您只需在最后一个元素子集的和中找到实现这一目标的最低值,然后您就知道,与值之和至少一样大的子集恰恰是与大于或等于K的初始子集组合在一起的子集,计算这些子集很容易,因为您对可能值的数组进行了排序。

P.S :边际优化是可能的,通过使用最小j_i序列,使F[i] + L[j_i] >= K是一个不增加的序列。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42554600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档