给定两个阵列的常用3包含N个整数和Q [] []包含K的查询,其中每个查询表示范围[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} 。
- 步骤2:对于查询[1,3] ,索引[ 1,3]处的元素增加1。此查询后的计数数组变为{1,1,1,1,0,0,0} 。
- 步骤3:类似地,对于下一个查询,count数组变为{1,1,1,1,1,1,1},最后,在第三个查询之后,count数组变为{1,1,2,2,1, 1} 。
- 步骤4:获得count数组后,其想法是使用排序以获得最大的总和。
- 步骤5:排序后,数组C [] = { 1,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];
}
// Variable to store the maximum sum
int ans = 0;
// Sorting both the arrays
sort(count, count + N);
sort(A, A + N);
// Loop to find the maximum sum
for (int i = N - 1; i >= 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
46
时间复杂度: O(N * log(N))