Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ O(2^(K/2))时间内K个元素的子集和_C++_Performance_Algorithm_Implementation - Fatal编程技术网

C++ O(2^(K/2))时间内K个元素的子集和

C++ O(2^(K/2))时间内K个元素的子集和,c++,performance,algorithm,implementation,C++,Performance,Algorithm,Implementation,标准的一个小小变化是,我们想从一组N个大小中找出K个大小的子集,其总和为S 的标准蛮力解决方案产生的复杂性为O(N^K)。但是,上面的链接提到了蛮力方法的一种变体,复杂性为O(N^(K/2)) 维基的文章说 一个更好的指数时间算法是已知的,它在时间上运行 O(2N/2)。该算法将N个元素任意分成两个集合 每件2件。对于这两个集合中的每一个集合,它都存储一个总和列表 其元素的所有2N/2可能子集。这两个列表中的每一个 然后进行排序。为此使用标准比较排序算法 步骤将花费时间O(2N/2N)。但是,给

标准的一个小小变化是,我们想从一组N个大小中找出K个大小的子集,其总和为S

的标准蛮力解决方案产生的复杂性为O(N^K)。但是,上面的链接提到了蛮力方法的一种变体,复杂性为O(N^(K/2))

维基的文章说

一个更好的指数时间算法是已知的,它在时间上运行 O(2N/2)。该算法将N个元素任意分成两个集合 每件2件。对于这两个集合中的每一个集合,它都存储一个总和列表 其元素的所有2N/2可能子集。这两个列表中的每一个 然后进行排序。为此使用标准比较排序算法 步骤将花费时间O(2N/2N)。但是,给定一个排序的总和列表 对于k个元素,可以使用 引入一个(k+1)st元素,这两个排序列表可以 合并在时间O(2k)中。因此,可以以排序的形式生成每个列表 时间为O(2N/2)。给定两个排序列表,算法可以检查 如果第一个数组的元素和第二个数组的元素 在时间O(2N/2)中求和为s。为此,算法通过 按降序排列的第一个数组(从最大元素开始) 第二个数组按递增顺序排列(从最小数组开始) 元素)。每当第一个数组中当前元素的和 并且第二个数组中的当前元素大于s 算法移动到第一个数组中的下一个元素。如果少一点 然后,算法移动到第二个数组中的下一个元素。 如果找到两个和为s的元素,它将停止

现在基本上是说,如果我们想找到大小为k的子集,我们计算n个散列大小为k/2的所有子集,以及它们的总和,总和是散列中的关键。然后检查两组大小(k/2)的总和是否达到S

我理解这个算法,但不知道如何去实现它。 散列整数(Sum),值为列表元组,其中包含实际集合的(K/2)索引

如何在C++中有效地实现它?使用什么数据结构? 由于大小总和(k/2)元素可以且将是非唯一的,因此我们不能使用映射,我们需要一个多映射或类似的东西。

从基本O(2^n)暴力算法开始

改进的算法,称为Mead in Mead算法,将输入列表拆分为大小相等的一半。前半部分受基本蛮力算法的约束,在该算法中生成所有子集,计算它们的和,并与目标进行比较。有可能但不太可能在上半年找到目标。如果不是,算法将生成后半部分的所有子集,并检查每个和,以查看目标和和和之间的差异是否是前半部分的和,在这种情况下,已找到所需的子集


我在我的博客上发表了一篇文章。

你还需要检查两组大小为k/2的数据是否没有任何公共元素。当然,这就是为什么我们需要存储索引以及它们的总和。