给定一个由N 个整数组成的数组arr[]和一个数组Q[][] ,其中每一行表示一个范围{l, r} ( 0 ≤ l ≤ r ≤ N – 1 )。任务是通过重新排列除Q[][] 中给出的范围内的元素之外的数组,找到从索引0开始的所有子数组的最大总和。
例子:
Input: arr[] = {-8, 4, -2, -6, 4, 7, 1}, Q[][] = {{0, 0}, {4, 5}}Output: -15
Explanation:
The given array can be rearranged as {-8, 4, 1, -2, 4, 7, -6}. Now, the sum of all the subarrays starting from the first index are:
Sum of arr[0, 0] = -8
Sum of arr[0, 1] = -8 + 4 = -4
Sum of arr[0, 2] = -8 + 4 + 1 = -3
Sum of arr[0, 3] = -8 + 4 + 1 + (-2) = -5
Sum of arr[0, 4] = -8 + 4 +1 + (-2) + 4 = -1
Sum of arr[0, 5] = -8 + 4 + 1 + (-2) + 4 + 7= 6
Sum of arr[0, 6] = -8 + 4 +1 + (-2) + 4 + 7 + (-6) = 0
The total sum = -8 + (-4) + (-3)+ (-5) + (-1) + 6 + 0 = -15
Input: arr[] = {-8, 4, 3}, Q[][] = {{0, 2}}
Output: -13
Explanation: All elements are present in the given set of ranges. Therefore, no element can rearranged. Now, the sum of all subarrays from the first index are:
Sum of arr[0, 0] = -8
Sum of arr[0, 1] = -8 + 4 = -4
Sum of arr[0, 2] = -8 + 4 + 3 = -1
Total sum = -8 + (-4) + (-1) = -13
方法:思路是先找到不能重排的元素。然后,将剩余元素按降序排序并将它们分配给索引,以便将最大的元素分配给允许重新排列的最小索引。请按照以下步骤解决问题:
- 创建一个向量s和v分别存储可以重新排列的索引和元素。
- 遍历每个范围{l, r}的元素并将它们标记为已访问。
- 如果未标记为已访问,则遍历给定数组并存储索引i 。
- 按降序对向量v进行排序。
- 将给定数组中的元素作为arr[s[i]] = v[i]插入,其中i最多为允许重新排列的元素数。
- 完成上述步骤后,打印给定数组的前缀和之和作为最大和。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function that finds the maximum sum
// all subarrays from the starting index
// after rearranging the array
int maxSum(int n, int a[], int l[][2], int q)
{
// Stores elements after rearranging
vector v;
// Keeps track of visited elements
int d[n] = { 0 };
// Traverse the queries
for (int i = 0; i < q; i++) {
// Mark elements that are not
// allowed to rearranged
for (int x = l[i][0];
x <= l[i][1]; x++) {
if (d[x] == 0) {
d[x] = 1;
}
}
}
// Stores the indices
set st;
// Get indices and elements that
// are allowed to rearranged
for (int i = 0; i < n; i++) {
// Store the current index and
// element
if (d[i] == 0) {
v.push_back(a[i]);
st.insert(i);
}
}
// Sort vector v in descending order
sort(v.begin(), v.end(),
greater());
// Insert elements in array
int c = 0;
for (auto it : st) {
a[it] = v;
c++;
}
// Stores the resultant sum
int pref_sum = 0;
// Stores the prefix sums
int temp_sum = 0;
// Traverse the given array
for (int i = 0; i < n; i++) {
temp_sum += a[i];
pref_sum += temp_sum;
}
// Return the maximum sum
return pref_sum;
}
// Driver Code
int main()
{
// Given array
int arr[] = { -8, 4, -2, -6, 4, 7, 1 };
// Given size
int N = sizeof(arr) / sizeof(arr[0]);
// Queries
int q[][2] = { { 0, 0 }, { 4, 5 } };
// Number of queries
int queries = sizeof(q) / sizeof(q[0]);
// Function Call
cout << maxSum(N, arr, q, queries);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG
{
// Function that finds the maximum sum
// all subarrays from the starting index
// after rearranging the array
static int maxSum(int n, int a[], int [][]l, int q)
{
// Stores elements after rearranging
Vector v = new Vector<>();
// Keeps track of visited elements
int []d = new int[n];
// Traverse the queries
for (int i = 0; i < q; i++)
{
// Mark elements that are not
// allowed to rearranged
for (int x = l[i][0];
x <= l[i][1]; x++)
{
if (d[x] == 0)
{
d[x] = 1;
}
}
}
// Stores the indices
HashSet st = new HashSet<>();
// Get indices and elements that
// are allowed to rearranged
for (int i = 0; i < n; i++)
{
// Store the current index and
// element
if (d[i] == 0)
{
v.add(a[i]);
st.add(i);
}
}
// Sort vector v in descending order
Collections.sort(v);
Collections.reverse(v);
// Insert elements in array
int c = 0;
for (int it : st)
{
a[it] = v.get(c);
c++;
}
// Stores the resultant sum
int pref_sum = 0;
// Stores the prefix sums
int temp_sum = 0;
// Traverse the given array
for (int i = 0; i < n; i++)
{
temp_sum += a[i];
pref_sum += temp_sum;
}
// Return the maximum sum
return pref_sum;
}
// Driver Code
public static void main(String[] args)
{
// Given array
int []arr = { -8, 4, -2, -6, 4, 7, 1 };
// Given size
int N = arr.length;
// Queries
int [][]q = { { 0, 0 }, { 4, 5 } };
// Number of queries
int queries = q.length;
// Function Call
System.out.print(maxSum(N, arr, q, queries));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program for the
# above approach
# Function that finds the
# maximum sum all subarrays
# from the starting index
# after rearranging the array
def maxSum(n, a, l, q):
# Stores elements after
# rearranging
v = []
# Keeps track of visited
# elements
d = [0] * n
# Traverse the queries
for i in range(q):
# Mark elements that are not
# allowed to rearranged
for x in range(l[i][0],
l[i][1] + 1):
if (d[x] == 0):
d[x] = 1
# Stores the indices
st = set([])
# Get indices and elements
# that are allowed to rearranged
for i in range(n):
# Store the current index and
# element
if (d[i] == 0):
v.append(a[i])
st.add(i)
# Sort vector v in descending
# order
v.sort(reverse = True)
# Insert elements in array
c = 0
for it in st:
a[it] = v
c += 1
# Stores the resultant sum
pref_sum = 0
# Stores the prefix sums
temp_sum = 0
# Traverse the given array
for i in range(n):
temp_sum += a[i]
pref_sum += temp_sum
# Return the maximum sum
return pref_sum
# Driver Code
if __name__ == "__main__":
# Given array
arr = [-8, 4, -2,
-6, 4, 7, 1]
# Given size
N = len(arr)
# Queries
q = [[0, 0], [4, 5]]
# Number of queries
queries = len(q)
# Function Call
print(maxSum(N, arr, q, queries))
# This code is contributed by Chitranayal
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function that finds the maximum sum
// all subarrays from the starting index
// after rearranging the array
static int maxSum(int n, int []a, int [,]l, int q)
{
// Stores elements after rearranging
List v = new List();
// Keeps track of visited elements
int []d = new int[n];
// Traverse the queries
for (int i = 0; i < q; i++)
{
// Mark elements that are not
// allowed to rearranged
for (int x = l[i, 0];
x <= l[i, 1]; x++)
{
if (d[x] == 0)
{
d[x] = 1;
}
}
}
// Stores the indices
HashSet st = new HashSet();
// Get indices and elements that
// are allowed to rearranged
for (int i = 0; i < n; i++)
{
// Store the current index and
// element
if (d[i] == 0)
{
v.Add(a[i]);
st.Add(i);
}
}
// Sort vector v in descending order
v.Sort();
v.Reverse();
// Insert elements in array
int c = 0;
foreach (int it in st)
{
a[it] = v;
c++;
}
// Stores the resultant sum
int pref_sum = 0;
// Stores the prefix sums
int temp_sum = 0;
// Traverse the given array
for (int i = 0; i < n; i++)
{
temp_sum += a[i];
pref_sum += temp_sum;
}
// Return the maximum sum
return pref_sum;
}
// Driver Code
public static void Main(String[] args)
{
// Given array
int []arr = { -8, 4, -2, -6, 4, 7, 1 };
// Given size
int N = arr.Length;
// Queries
int [,]q = { { 0, 0 }, { 4, 5 } };
// Number of queries
int queries = q.GetLength(0);
// Function Call
Console.Write(maxSum(N, arr, q, queries));
}
}
// This code is contributed by 29AjayKumar
Javascript
-15
时间复杂度: O(N 2 )
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。