📌  相关文章
📜  重新排列给定范围所排除的数组元素,以最大化从第一个索引开始的子数组的总和

📅  最后修改于: 2021-05-04 13:33:28             🧑  作者: Mango

给定一个由n个整数组成的数组arr []和一个数组Q [] [] ,其中每行表示一个范围{l,r} ( 0≤l≤r≤N – 1 )。任务是通过重新排列除Q [] []中给定范围内的元素之外的数组,找到从索引0开始的所有子数组的最大和。

例子:

方法:想法是首先找到无法重新排列的元素。然后,按降序对其余元素进行排序,然后将它们分配给索引,以便将最大的元素分配给允许重新排列的最小索引。请按照以下步骤解决问题:

  • 创建向量sv来分别存储可以重新排列的索引和元素。
  • 遍历每个范围{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


输出:
-15

时间复杂度: O(N 2 )
辅助空间: O(N)