给定一个大小为N的数组 arr[]和一个整数M,任务是在将数组中任何元素的符号更改恰好M次后,找到该数组的最大和。允许多次更改同一元素的符号。
例子:
Input: arr[ ] = {-3, 7, -1, -5, -3}, M = 4
Output: 19
Explanation:
4 operations on the array can be performed as,
Operation 1: Change the sign of arr[0] -> {3, 7, -1, -5, -3}
Operation 2: Change the sign of arr[2] -> {3, 7, 1, -5, -3}
Operation 3: Change the sign of arr[3] -> {3, 7, 1, 5, -3}
Operation 4: Change the sign of arr[4] -> {3, 7, 1, 5, 3}
The maximum sum of array obtained is 19.
Input: arr[ ] = {-4, 2, 3, 1}, M = 3
Output: 10
方法:解决这个问题的主要思想是在每次迭代中翻转数组的最小数。通过这样做,负值将变为正值,并且数组总和将最大化。
请按照以下步骤解决问题:
- 初始化一个最小优先级队列,比如pq[],并推送数组arr[] 的所有元素。
- 初始化一个变量,比如sum = 0,以存储数组的最大和。
- 迭代 while 循环直到 M 大于0并执行以下操作:
- 从优先级队列中弹出并从变量sum 中减去它。
- 将弹出元素的符号乘以-1并将其添加到sum 中。
- 将新的翻转元素推入优先级队列,并从M 中减去 1 。
- 最后,打印存储在变量sum 中的最大和。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum sum
// with M flips
void findMaximumSumWithMflips(
int arr[], int N, int M)
{
// Declare a priority queue
// i.e. min heap
priority_queue, greater > pq;
// Declare the sum as zero
int sum = 0;
// Push all elements of the
// array in it
for (int i = 0; i < N; i++) {
pq.push(arr[i]);
sum += arr[i];
}
// Iterate for M times
while (M--) {
// Get the top element
sum -= pq.top();
// Flip the sign of the
// top element
int temp = -1 * pq.top();
// Remove the top element
pq.pop();
// Update the sum
sum += temp;
// Push the temp into
// the queue
pq.push(temp);
}
cout << sum;
}
// Driver program
int main()
{
int arr[] = { -3, 7, -1, -5, -3 };
// Size of the array
int N = sizeof(arr) / sizeof(arr[0]);
int M = 4;
findMaximumSumWithMflips(arr, N, M);
return 0;
}
19
19
时间复杂度: O(NLogN)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。