贪心算法——最小化完成任务的操作次数
Greedy algorithm - minimize number of operations to complete task
我正在尝试解决编程难题。为了方便起见,我总结如下:
Given an array, A, of positive integers. In one operation, we can choose one of the elements in the array, A[i] and reduce it by a fixed amount X. At the same time, the rest of the elements will be reduced by a fixed amount Y. We need to find the minimum number of operations to reduce all elements to a non-positive number (i.e. 0 and below).
Constraints:
1 <= |A| <= 1e5
1 <= A[i] <= 1e9
1 <= Y < X <= 1e9
Time limit: 1 second
例如,设 X = 10,Y = 4 和 A = {20, 20}。
此示例的最佳方法是:
操作一:选择项目0。
A = {10, 16}
操作2:选择项目0。
A = {0, 12}
操作3:选择项目1。
A = {-4, 2}
操作4:选择项目1。
A = {-8, -8}
因此,答案是 4。
我的做法:
继续选择数组中的当前最大元素并将其减少X(并将其余元素减少Y)。显然,由于 X 和 Y 的值可能很小(即我的算法将执行的迭代次数下限为 max(A[i]) / 2),这种方法会超过时间限制。
有人可以告诉我更好的解决方案吗?
这个问题可以用二分查找来解决
首先,我们要检查在a
次操作中,能否让所有元素都变成<=0;我们可以检查每个元素的最小操作数 b
,这样如果我们为 b
操作减去 x
并为剩余的 a-b
减去 y
] 操作,则元素的结果值将变为 <= 0。将所有这些数字加在一起,如果 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;
时间复杂度O(n log max(A))
.
我正在尝试解决编程难题。为了方便起见,我总结如下:
Given an array, A, of positive integers. In one operation, we can choose one of the elements in the array, A[i] and reduce it by a fixed amount X. At the same time, the rest of the elements will be reduced by a fixed amount Y. We need to find the minimum number of operations to reduce all elements to a non-positive number (i.e. 0 and below).
Constraints:
1 <= |A| <= 1e5
1 <= A[i] <= 1e9
1 <= Y < X <= 1e9
Time limit: 1 second
例如,设 X = 10,Y = 4 和 A = {20, 20}。
此示例的最佳方法是:
操作一:选择项目0。
A = {10, 16}
操作2:选择项目0。
A = {0, 12}
操作3:选择项目1。
A = {-4, 2}
操作4:选择项目1。
A = {-8, -8}
因此,答案是 4。
我的做法:
继续选择数组中的当前最大元素并将其减少X(并将其余元素减少Y)。显然,由于 X 和 Y 的值可能很小(即我的算法将执行的迭代次数下限为 max(A[i]) / 2),这种方法会超过时间限制。
有人可以告诉我更好的解决方案吗?
这个问题可以用二分查找来解决
首先,我们要检查在a
次操作中,能否让所有元素都变成<=0;我们可以检查每个元素的最小操作数 b
,这样如果我们为 b
操作减去 x
并为剩余的 a-b
减去 y
] 操作,则元素的结果值将变为 <= 0。将所有这些数字加在一起,如果 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;
时间复杂度O(n log max(A))
.