我正在尝试解决编程挑战性问题。为了方便起见,我将其总结如下:
给出一个正整数数组A。在一个操作中,我们可以选择数组中元素的[strong>一个,即A [i]并将其减少固定数量X。与此同时,其余元素将减少a固定数量Y。我们需要找到最小操作数,以将所有元素减少到非正数(即0和以下)。
约束:
1 <= | A | <= 1e5
1 <= A [i] <= 1e9
1 <= Y时限:1秒
例如,让X = 10,Y = 4和A = {20,20}。
此示例的最佳方法是:
操作1:选择项目0。
A = {10,16}
操作2:选择项目0。
A = {0,12}
操作3:选择项目1。
A = {-4,2}
操作4:选择项目1。
A = {-8,-8}
因此,答案是4。
我的方法:
继续选择数组中的 current 个最大元素,并将其减少X(将其余元素减少Y)。显然,由于X和Y的值可能较小(即我的算法将执行的迭代次数以max(A [i])/ 2为下限),因此该方法将超过时间限制。
有人可以建议我提供更好的解决方案吗?
答案 0 :(得分:3)
可以通过使用二进制搜索解决此问题
首先,我们要检查是否在a
操作中,是否可以使所有元素变为<= 0;我们可以检查每个元素的最小操作数b
,这样,如果我们为x
个操作减去b
而为其余{{1}减去y
}操作,则元素的结果值将变为<=0。将所有这些数字加在一起,如果使用a-b
,则意味着可以使用sum <= a
操作。
然后,我们可以应用二进制搜索来搜索有效的a
。
a
时间复杂度int st = 0;
int ed = max element / y + 1;
int result = ed;
while(start <= end){
int mid = (st + ed)/2;
int sum = 0;
for(int i : A){
sum += minTimesMinusX(i, mid);
}
if(sum <= mid){
result = mid;
ed = mid - 1;
}else{
st = mid + 1;
}
}
return result;
。