Arrays 如果组的和至少为K,则从数组中选择元素的方法数 问题:如果我们给出整数n、k和数组n的大小,如1<p>,对于这个问题,你可以使用一个“中间碰巧”,类似于通常用来解决子集和问题在时间 O(n×2 ^(n/2))< /> >(和你将具有相同的复杂度)。
首先,计算第一个Arrays 如果组的和至少为K,则从数组中选择元素的方法数 问题:如果我们给出整数n、k和数组n的大小,如1<p>,对于这个问题,你可以使用一个“中间碰巧”,类似于通常用来解决子集和问题在时间 O(n×2 ^(n/2))< /> >(和你将具有相同的复杂度)。,arrays,algorithm,bit,Arrays,Algorithm,Bit,首先,计算第一个N/2元素的2^N/2可能的和,并存储它们。对最后的N/2元素执行相同的操作 现在按递增顺序对两个集合进行排序。排序n元素需要时间O(n log n),因此这里是O(n2^(n/2))成本。让我们将这两个排序集分别称为F和L(第一个和最后一个) 然后,执行以下操作: 设置res=0 对于从0到2的i^(N/2)-1{ 求{0,…,2^(N/2)-1}中的最小j_i,使得F[i]+L[j_i]>=K(使用二分法搜索) 如果存在这样的j_i,则将res增加(2^(N/2)-j_i)
N/2
元素的2^N/2
可能的和,并存储它们。对最后的N/2
元素执行相同的操作
现在按递增顺序对两个集合进行排序。排序n
元素需要时间O(n log n)
,因此这里是O(n2^(n/2))
成本。让我们将这两个排序集分别称为F
和L
(第一个和最后一个)
然后,执行以下操作:
设置res=0
对于从0到2的i^(N/2)-1{
求{0,…,2^(N/2)-1}中的最小j_i,使得F[i]+L[j_i]>=K(使用二分法搜索)
如果存在这样的j_i,则将res增加(2^(N/2)-j_i)
}
返回res
其思想是,对于第一个N/2
元素的每个子集,您可以查看有多少种方法可以选择最后一个N/2
元素的子集,从而使总和大于K
。为此,您只需在最后一个元素的子集的总和中找到实现这一点的最小值,然后您就知道,总和至少等于该值的子集正是与初始子集组合的子集,其总和大于或等于K
,计算这些值很容易,因为您对可能值的数组进行了排序
P.S.使用最小<代码> JSI I/CODE序列,使得<>代码> f[i] +L[jyi] >k</代码>是非递增序列,可以进行边际优化。
对于这个问题,可以使用类似于通常用于解决时间子集和问题的一个“满足中技巧”(o)(n×2 ^(n/2))。(您将拥有相同的复杂性) 首先,计算第一个N/2
元素的2^N/2
可能的和,并存储它们。对最后的N/2
元素执行相同的操作
现在按递增顺序对两个集合进行排序。排序n
元素需要时间O(n log n)
,因此这里是O(n2^(n/2))
成本。让我们将这两个排序集分别称为F
和L
(第一个和最后一个)
然后,执行以下操作:
设置res=0
对于从0到2的i^(N/2)-1{
求{0,…,2^(N/2)-1}中的最小j_i,使得F[i]+L[j_i]>=K(使用二分法搜索)
如果存在这样的j_i,则将res增加(2^(N/2)-j_i)
}
返回res
其思想是,对于第一个N/2
元素的每个子集,您可以查看有多少种方法可以选择最后一个N/2
元素的子集,从而使总和大于K
。为此,您只需在最后一个元素的子集的总和中找到实现这一点的最小值,然后您就知道,总和至少等于该值的子集正是与初始子集组合的子集,其总和大于或等于K
,计算这些值很容易,因为您对可能值的数组进行了排序
注:通过使用最小的
j_i
序列,使得F[i]+L[j_i]>=K
是一个非递增序列,可以实现边际优化。如果任何元素或元素组合大于K,那么添加任何元素都将大于K,假设所有元素都为正。在您的示例中,如果发现第一个和第三个元素符合标准,则自动获得集合(第一、第二、第三、(第一、第三、第四)、(第一、第二、第三、第四)如果任何元素或元素组合大于K,则添加任何元素仍将大于K,假设所有元素均为正值。在您的示例中,如果发现第一个和第三个元素符合标准,则会自动获得集合(第一、第二、第三、(第一、第三、第四)、(第一、第二、第三、第四)