选择数字以最大化间隔

时间:2016-05-15 15:33:04

标签: arrays algorithm dynamic-programming

有一个数组包含一个0到999之间的数字,严格按顺序增加。

例如

int[] array = {0, 24, 55, 124, 200, 259, 400, 503, 666, 797};

我要做的是实现一个选择N个数字的函数,以便最大化这些选中数字之间的距离的最小值。

例如,如果N是3,则拾取的数字是0,400,797,间隔是400和397;所以返回值是397(应该最大化)。如果我们选择其他数字集,则返回值将小于(或等于)397。

我想使用递归来实现它,但我很难对它进行编码。你想帮助我吗?

1 个答案:

答案 0 :(得分:2)

使用dynamic programing可以解决此问题。

如果我们在选择s[c][p]数字时将c定义为解决方案,并且最后选择的数字在输入数组中具有索引p

然后,我们可以将s[c][p]计算为max for i=0..p of max(s[c-1][p-i], array[p] - array[p-i])

在以下状态开头:s[1][0..n],其中n是输入数组的长度,应该具有值0

拥有s[1][0..n]我们现在可以使用给定的公式轻松计算s[2][0..n]s[2][0..n]我们现在可以轻松计算s[3][0..n] 等等...

整个问题的解决方案是max s[N][N-1..n],其中n是输入数组的长度,N是要选择的数字的数量。

此解决方案的时间复杂度为O(N*n^2) 说明:我们计算s[0..N][0..n]的值,其中每个计算的时间复杂度为O(n)

此解决方案的内存复杂性为O(n) 说明:要计算s[c][0..n],您只需要s[c-1][0..n],因此在每个时间点实际只需要2*n个内存。

编辑:您可以使用递归来实现所描述的算法,使用称为memoization(https://en.wikipedia.org/wiki/Memoization)的编程技术。