给定两个包含N 个整数的数组arr[]和包含K 个查询的Q[][] ,其中每个查询代表一个范围[L, R] 。任务是重新排列数组并找到所有子数组的最大可能总和,其中每个子数组由每个查询给出的[L, R]范围内的数组元素定义。
注意:在Q[][]数组中使用基于 1 的索引来表示范围。
例子:
Input: arr[] = { 2, 6, 10, 1, 5, 6 }, Q[][2] = {{1, 3}, {4, 6}, {3, 4}}
Output: 46
Explanation:
One possible way is to rearrange the array to arr[] = {2, 6, 10, 6, 5, 1}.
In this arrangement:
The sum of the subarray in the range [1, 3] = 2 + 6 + 10 = 18.
The sum of the subarray in the range [4, 6] = 6 + 5 + 1 = 12.
The sum of the subarray in the range [3, 4] = 10 + 6 = 16.
The total sum of all the subarrays = 46 which is the maximum possible.
Input: arr[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, Q[][2] = {{1, 4}, {5, 5}, {7, 8}, {8, 8}}
Output: 43
Explanation:
One possible way is to rearrange the array to arr[] = {2, 3, 4, 5, 6, 1, 7, 8}.
In this arrangement:
The sum of the subarray in the range [1, 4] = 2 + 3 + 4 + 5 = 14.
The sum of the subarray in the range [5, 5] = 6 = 6.
The sum of the subarray in the range [7, 8] = 7 + 8 = 15.
The sum of the subarray in the range [8, 8] = 8 = 8.
The total sum of all the subarrays = 43 which is the maximum possible.
方法:仔细观察,可以得出的一个结论是,当尽可能多的子数组中包含最大元素时,我们得到最大和。为此,我们需要通过迭代所有查询来找到每个索引被包含的次数。
例如:令数组为arr[] = {2, 6, 10, 6, 5, 1} ,查询为Q[][] = {{1, 3}, {4, 6}, {3, 4}} 。
- 步骤 1:创建一个大小为 N 的计数数组C[] 。因此,最初,计数数组C[] = {0, 0, 0, 0, 0, 0} 。
- 第二步:对于查询[1, 3] ,索引 [1, 3] 处的元素递增 1。此查询后的计数数组变为{1, 1, 1, 0, 0, 0} 。
- 第三步:同理,对于下一次查询,计数数组变为{1, 1, 1, 1, 1, 1},最后,第三次查询后,计数数组变为{1, 1, 2, 2, 1, 1} 。
- Step 4:得到count数组后,思路是用排序得到最大和。
- 第五步:排序后,数组C[] = {1, 1, 1, 1, 2, 2}和arr[] = {1, 2, 5, 6, 6, 10} 。最大可能总和是两个数组的加权总和,即:
sum = ((1 * 1) + (1 * 2) + (1 * 5) + (1 * 6) + (2 * 6) + (2 * 10)) = 46
下面是上述方法的实现:
C++
// C++ program to find the maximum sum
// after rearranging the array for K queries
#include
using namespace std;
// Function to find maximum sum after
// rearranging array elements
int maxSumArrangement(int A[], int R[][2],
int N, int M)
{
// Auxiliary array to find the
// count of each selected elements
int count[N];
// Initialize with 0
memset(count, 0, sizeof count);
// Finding count of every element
// to be selected
for (int i = 0; i < M; ++i) {
int l = R[i][0], r = R[i][1] + 1;
// Making it to 0-indexing
l--;
r--;
// Prefix sum array concept is used
// to obtain the count array
count[l]++;
if (r < N)
count[r]--;
}
// Iterating over the count array
// to get the final array
for (int i = 1; i < N; ++i) {
count[i] += count[i - 1];
}
for (int i = 0; i < N; ++i) {
cout<= 0; --i) {
ans += A[i] * count[i];
}
return ans;
}
// Driver code
int main()
{
int A[] = { 2, 6, 10, 1, 5, 6 };
int R[][2]
= { { 1, 3 }, { 4, 6 }, { 3, 4 } };
int N = sizeof(A) / sizeof(A[0]);
int M = sizeof(R) / sizeof(R[0]);
cout << maxSumArrangement(A, R, N, M);
return 0;
}
Java
// Java program to find the maximum sum
// after rearranging the array for K queries
import java.util.*;
class GFG
{
// Function to find maximum sum after
// rearranging array elements
static int maxSumArrangement(int A[], int R[][],
int N, int M)
{
// Auxiliary array to find the
// count of each selected elements
int count[] = new int[N];
int i;
// Finding count of every element
// to be selected
for ( i = 0; i < M; ++i) {
int l = R[i][0], r = R[i][1] + 1;
// Making it to 0-indexing
l--;
r--;
// Prefix sum array concept is used
// to obtain the count array
count[l]++;
if (r < N)
count[r]--;
}
// Iterating over the count array
// to get the final array
for (i = 1; i < N; ++i) {
count[i] += count[i - 1];
}
// Variable to store the maximum sum
int ans = 0;
// Sorting both the arrays
Arrays.sort( count);
Arrays.sort(A);
// Loop to find the maximum sum
for (i = N - 1; i >= 0; --i) {
ans += A[i] * count[i];
}
return ans;
}
// Driver code
public static void main(String []args)
{
int A[] = { 2, 6, 10, 1, 5, 6 };
int R[][]
= { { 1, 3 }, { 4, 6 }, { 3, 4 } };
int N = A.length;
int M = R.length;
System.out.print(maxSumArrangement(A, R, N, M));
}
}
// This code is contributed by chitranayal
Python3
# Python3 program to find the maximum sum
# after rearranging the array for K queries
# Function to find maximum sum after
# rearranging array elements
def maxSumArrangement( A, R, N, M):
# Auxiliary array to find the
# count of each selected elements
# Initialize with 0
count = [0 for i in range(N)]
# Finding count of every element
# to be selected
for i in range(M):
l = R[i][0]
r = R[i][1] + 1
# Making it to 0-indexing
l = l - 1
r = r - 1
# Prefix sum array concept is used
# to obtain the count array
count[l] = count[l] + 1
if (r < N):
count[r] = count[r] - 1
# Iterating over the count array
# to get the final array
for i in range(1, N):
count[i] = count[i] + count[i - 1]
# Variable to store the maximum sum
ans = 0
# Sorting both the arrays
count.sort()
A.sort()
# Loop to find the maximum sum
for i in range(N - 1, -1, -1):
ans = ans + A[i] * count[i]
return ans
# Driver code
A = [ 2, 6, 10, 1, 5, 6 ]
R = [ [ 1, 3 ], [ 4, 6 ], [ 3, 4 ] ]
N = len(A)
M = len(R)
print(maxSumArrangement(A, R, N, M))
# This code is contributed by Sanjit_Prasad
C#
// C# program to find the maximum sum
// after rearranging the array for K queries
using System;
class GFG
{
// Function to find maximum sum after
// rearranging array elements
static int maxSumArrangement(int []A, int [,]R,
int N, int M)
{
// Auxiliary array to find the
// count of each selected elements
int []count = new int[N];
int i;
// Finding count of every element
// to be selected
for ( i = 0; i < M; ++i) {
int l = R[i, 0], r = R[i, 1] + 1;
// Making it to 0-indexing
l--;
r--;
// Prefix sum array concept is used
// to obtain the count array
count[l]++;
if (r < N)
count[r]--;
}
// Iterating over the count array
// to get the readonly array
for (i = 1; i < N; ++i) {
count[i] += count[i - 1];
}
// Variable to store the maximum sum
int ans = 0;
// Sorting both the arrays
Array.Sort( count);
Array.Sort(A);
// Loop to find the maximum sum
for (i = N - 1; i >= 0; --i) {
ans += A[i] * count[i];
}
return ans;
}
// Driver code
public static void Main(String []args)
{
int []A = { 2, 6, 10, 1, 5, 6 };
int [,]R
= { { 1, 3 }, { 4, 6 }, { 3, 4 } };
int N = A.Length;
int M = R.GetLength(0);
Console.Write(maxSumArrangement(A, R, N, M));
}
}
// This code is contributed by Princi Singh
Javascript
46
时间复杂度: O(N* log(N))
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live