如何找到最小正数K,使得对于数组中的每个项目,从[-K,K]中添加或减去数字可以导致严格上升的数组?
例如:
我的猜测如下
定义f(i,j)= a [i] - a [j] + ji-1(要求i< j和a [i]> a [j]:所有逆序对)
最小K必须满足条件:
2 * K> max f(i,j)
因为如果一对(i,j)不是按升序排列,则[j]最多只能加K,a [i]最多可以减去K,并且你需要在[a]之间留出空间i]和a [j](因为它是严格的升序), 所以(a [j] + K) - (a [i] - K)应大于(j-i-1)(它们之间的长度)。
所以 k> = max f(i,j)/ 2 + 1
问题是我不能证明k = max f(i,j)/ 2 + 1是否可以?
更多线索:
我已经考虑过找一个算法来确定给定的K是否足够,然后我们 可以使用该算法从可能的最小值开始尝试每个K,以找到解决方案。
我想出一个像这样的算法:
for i in n->1 # n is array length
if i == n:
add K to a[i] # add the max to the last item won't affect order
else:
# the method is try to make a[i] as big as possible and still < a[i+1]
find a num k1 in [-K, K] to make a[i] to bottom closest to a[i+1]-1
if found:
add k1 to a[i]
else no k1 in [-K, K] can make a[i] < a[i+1]
return false
return true
我也是这样的算法是对还是
答案 0 :(得分:11)
我认为你的猜测是正确的,但我不能证明这一点:-)相反,我会先简化你的问题
通过“添加”K来如何找到最小正数K,使得对于数组中的每个项目,在[-K,K]中添加或减去数字会导致严格升序的数组?
到这个等价的:
如何找到最小正数2 * K,以便对于数组中的每个项目,从[0,2 * K]添加数字可以导致严格升序的数组?
我们可以通过迭代数组并跟踪所需的2K值来轻松解决这个问题,以满足条件。它与@ ruakh的相似,但没有减法:
k2 = 0
last = arr[0]
for each cur in arr from 1
if cur + k2 <= last
last ++
k2 = last - cur
else
last = cur
k = ceil ( k2 / 2 )
答案 1 :(得分:8)
我认为你有点过分思考。您可以迭代数组的元素,跟踪 K 的当前最小可能值,以及给定的值的最后看到的元素的当前最小可能值>ķ。每当您发现一个证明 K 太小的元素时,您可以相应地增加它。
例如,在Java中:
int[] array = { 10, 2, 20 };
int K = 0, last = array[0];
for (int i = 1; i < array.length; ++i) {
if (last >= array[i] + K) {
// If we're here, then our value for K wasn't enough: the minimum
// possible value of the previous element after transformation is still
// not less than the maximum possible value of the current element after
// transformation; so, we need to increase K, allowing us to decrease
// the former and increase the latter.
int correction = (last - (array[i] + K)) / 2 + 1;
K += correction;
last -= correction;
++last;
} else {
// If we're here, then our value for K was fine, and we just need to
// record the minimum possible value of the current value after
// transformation. (It has to be greater than the minimum possible value
// of the previous element, and it has to be within the K-bound.)
if (last < array[i] - K) {
last = array[i] - K;
} else {
++last;
}
}
}