找到大小为k的子集,使得值之间的最小距离最大

时间:2014-03-15 14:10:51

标签: c arrays algorithm dynamic-programming

假设我有一个包含n个整数的数组 如何找到大小为k的子集,使得子集中所有整数对之间的minimum距离为maximized,我的意思是它们距离最远。

示例:数组a[]={1,2,6,7,10}k=3
subset = {1,6,10},最小距离为4,介于10到6之间 错误的子集
{1,7,10},最小距离为3
{1,2,6},最小距离为1

我想出了一个解决方案:

1)排序阵列
2)选择一个[0],现在在数组中找到ceil(a [0] + x)= Y ....然后是ceil(Y + x),依此类推k-1时间,第k个元素也将是a[n-1]

查找x
dp[i,j]x,用于从第一个i元素中选择j个元素 最后,我们希望dp[n][k] <{1}}

但我在寻找x时遇到了问题。

  

dp [i,j] = max(min(dp [k,j-1],dp [i] -A [k]))
                  在k = 1到i-1,i = 2到n,j = 2到i

     

dp [i] [1] = 0,i = 1到n

编辑:我想纠正动态编程解决方案,虽然我知道x可以通过二进制搜索x找到。

更新2 :我已更新代码,但仍无法获得正确的解决方案。请指出错误 代码:http://ideone.com/J5vvR9

更新3 :感谢@Gassa,@ Niklas B.和@Fallen提供的答案!

3 个答案:

答案 0 :(得分:2)

如果时间允许搜索以获取x的可能值,我认为查找 x没有必要。只需添加外部循环,这将是对答案的二元搜索(即最小距离,我们称之为x)。

修复x后,您可以从a[0]开始贪婪地选择值。下一个选定的值将是a[i]最小ia[i] - a[0] >= x。第三个是a[j]j最小,a[j] - a[i] >= x,依此类推。如果您能够以这种方式选择至少k个值,则实际答案至少是当前x;如果没有,答案就小于x

总运行时间为O(n log(C)),其中C是数组中可能值的总数。比如说,如果数组中的整数是0到1000000,C将是1000001,log(C)(向上舍入)将是20.首先,你尝试x = 500000;如果它失败了,你留下的范围是[0; 500000)答案;如果没有,范围[500000; 1000000]等。

答案 1 :(得分:2)

基数应该是:

dp[i][1] = INFINITY for i = 1 to n

原因是minimum of an empty set是正无穷大。

实际上,对于某些a[i] - a[j]i,任何大于j的最大值的整数都可以作为INFINITY常量。

此外,正确的过渡将是:

dp[i,j] = max{for k=1 to i-1} (min(dp[k,j-1], a[i]-a[k]))

答案 2 :(得分:1)

对X值进行二进制搜索。然后对于每个这样的x,编写一个DP / Greedy函数,检查是否存在一个结果(元素之间的最大距离)大于或等于X的数组。 / p>

正确性如果对于任何X,我们可以有M个元素,使得它们之间的最小距离大于或等于X,然后对于每个x,x&lt; X,至少这个相同的数组将作为结果服务器。并且对于任何X,如果没有M个元素,使得元素之间的最小距离大于或等于X,则对于无x,x> 0。 X,M这样的元素是可用的。所以我们可以在X上进行二进制搜索。

相关问题