📌  相关文章
📜  最大化数组总和,除了来自 [i, i+X] 的元素之外的所有 i 使得 arr[i] > K

📅  最后修改于: 2022-05-13 01:56:09.486000             🧑  作者: Mango

最大化数组总和,除了来自 [i, i+X] 的元素之外的所有 i 使得 arr[i] > K

给定一个大小为N的数组arr[]和两个整数XK ,任务是找到通过重新排列数组元素可以获得的最大分数,其中分数计算为数组元素的总和,除了索引i中的下一个X元素,例如arr[i] > K对于范围[0, N)中 i 的所有可能值。

例子:

方法:给定的问题可以使用贪心方法来解决。创建两个数组, big[]包含大于K的整数, small[]包含小于K的整数。可以看出,如果总和中必须包含的大于K的元素个数为i ,则数组中必须至少存在(i − 1)(X + 1) + 1 个元素。因此,对于每个可能的 i,从总和中排除 ( (i − 1)(X + 1) + 1 ) – i small[]数组的最小元素。每个i的所有可能总和的最大值是所需的结果。

下面是上述方法的实现:

C++
// C++ program, for the above approach
#include 
using namespace std;
 
const int maxn = 1e5;
 
// Utility function to calculate the
// sum of elements as a prefix array
void calc(int arr[], int N)
{
    sort(arr + 1, arr + N + 1);
    reverse(arr + 1, arr + N + 1);
 
    for (int i = 1; i <= N; i++) {
        arr[i] += arr[i - 1];
    }
}
 
// Function to find the maximum score
// that can be achieved by rearranging
// the elements of given array
int maxScore(int arr[], int X, int K, int N)
{
    // Arrays to store small and big elements
    int small[maxn + 5], big[maxn + 5];
    int k = 0, l = 0;
 
    // Iterate and segregate big and
    // small elements
    for (int i = 0; i < N; i++) {
        if (arr[i] > K) {
            big[++k] = arr[i];
        }
        else {
            small[++l] = arr[i];
        }
    }
    // If k = 0, return the sum
    // of small[]
    if (k == 0) {
        int sum = 0;
        for (int i = 1; i <= N; i++) {
            sum += small[i];
        }
        return sum;
    }
    // Prefix sums of small[]
    // and big[]
    calc(big, k);
    calc(small, l);
 
    // Initialize small[l] within the range
    fill(small + l + 1, small + N + 1, small[l]);
 
    // Variable to store the answer
    int res = 0;
    for (int i = (k + X) / (1 + X); i <= k; i++) {
        if (1ll * (i - 1) * (X + 1) + 1 <= N) {
 
            // Update res with maximum one
            res = max(
                res,
                big[i]
                    + small[N - 1ll
                           * (i - 1)
                           * (X + 1) - 1]);
        }
    }
    // Return res
    return res;
}
 
// Driver Code
int main()
{
    int arr[] = { 9, 13, 16, 21, 6 };
    int X = 2;
    int K = 15;
    int N = sizeof(arr) / sizeof(arr[0]);
 
    cout << maxScore(arr, X, K, N);
 
    return 0;
}


Java
// Java program, for the above approach
import java.util.*;
 
class GFG{
 
static int maxn = (int)1e5;
 
// Utility function to calculate the
// sum of elements as a prefix array
static void calc(int arr[], int N)
{
    Arrays.sort(arr);
    arr = reverse(arr);
 
    for(int i = 1; i <= N; i++)
    {
        arr[i] += arr[i - 1];
    }
}
 
static int[] reverse(int a[])
{
    int i, n = a.length + 1, t;
    for(i = 1; i < n / 2; i++)
    {
        t = a[i];
        a[i] = a[n - i - 1];
        a[n - i - 1] = t;
    }
    return a;
}
 
// Function to find the maximum score
// that can be achieved by rearranging
// the elements of given array
static int maxScore(int arr[], int X, int K, int N)
{
     
    // Arrays to store small and big elements
    int []small = new int[maxn + 5];
    int big[] = new int[maxn + 5];
    int k = 0, l = 0;
 
    // Iterate and segregate big and
    // small elements
    for(int i = 0; i < N; i++)
    {
        if (arr[i] > K)
        {
            big[++k] = arr[i];
        }
        else
        {
            small[++l] = arr[i];
        }
    }
     
    // If k = 0, return the sum
    // of small[]
    if (k == 0)
    {
        int sum = 0;
        for(int i = 1; i <= N; i++)
        {
            sum += small[i];
        }
        return sum;
    }
     
    // Prefix sums of small[]
    // and big[]
    calc(big, k);
    calc(small, l);
 
    // Initialize small[l] within the range
    // fill(small + l + 1, small + N + 1, small[l]);
    for(int i = l + 1; i <= N; i++)
    {
        small[i] = small[l];
    }
     
    // Variable to store the answer
    int res = 0;
    for(int i = (k + X) / (1 + X); i <= k; i++)
    {
        if (1 * (i - 1) * (X + 1) + 1 <= N)
        {
             
            // Update res with maximum one
            res = Math.max(
                res, big[i] + small[N - 1 * (i - 1)  *
                                   (X + 1) - 1]);
        }
    }
     
    // Return res
    return res;
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 9, 13, 16, 21, 6 };
    int X = 2;
    int K = 15;
    int N = arr.length;
 
    System.out.print(maxScore(arr, X, K, N));
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program, for the above approach
maxn = int(1e5)
     
# Utility function to calculate the
# sum of elements as a prefix array
def calc(arr, N) :
     
    arr.sort()
    arr[::-1]
 
    for i in range(1, N+1):
        arr[i] += arr[i - 1]
     
# Function to find the maximum score
# that can be achieved by rearranging
# the elements of given array
def maxScore(arr, X, K, N) :
     
    # Arrays to store small and big elements
    small = [10] * (maxn + 5)
    big = [10] * (maxn + 5)
    k = 0
    l = 0
 
    # Iterate and segregate big and
    # small elements
    for i in range(N):
        if (arr[i] > K) :
            big[++k] = arr[i]
         
        else :
            small[++l] = arr[i]
         
     
    # If k = 0, return the sum
    # of small[]
    if (k == 0) :
        sum = 0
        for i in range(1, N+1):
            sum += small[i]
         
        return sum
     
    # Prefix sums of small[]
    # and big[]
    calc(big, k)
    calc(small, l)
 
    # Initialize small[l] within the range
    for i in range(l + 1, N+1):
        small[i] = small[l]
         
 
    # Variable to store the answer
    res = 0
    for i in range((k + X) / (1 + X), k+1):
        if (1 * (i - 1) * (X + 1) + 1 <= N) :
 
            # Update res with maximum one
            res = max(
                res,
                big[i]
                    + small[N - 1 * (i - 1)
                           * (X + 1) - 1])
         
    # Return res
    return res
 
# Driver Code
arr = [ 9, 13, 16, 21, 6 ]
X = 2
K = 15
N = len(arr)
 
print(maxScore(arr, X, K, N))
 
# This code is contributed by sanjoy_62.


C#
// C# program, for the above approach
using System;
class GFG {
 
    static int maxn = (int)1e5;
 
    // Utility function to calculate the
    // sum of elements as a prefix array
    static void calc(int[] arr, int N)
    {
        Array.Sort(arr);
        arr = reverse(arr);
 
        for (int i = 1; i <= N; i++) {
            arr[i] += arr[i - 1];
        }
    }
 
    static int[] reverse(int[] a)
    {
        int i, n = a.Length + 1, t;
        for (i = 1; i < n / 2; i++) {
            t = a[i];
            a[i] = a[n - i - 1];
            a[n - i - 1] = t;
        }
        return a;
    }
 
    // Function to find the maximum score
    // that can be achieved by rearranging
    // the elements of given array
    static int maxScore(int[] arr, int X, int K, int N)
    {
 
        // Arrays to store small and big elements
        int[] small = new int[maxn + 5];
        int[] big = new int[maxn + 5];
        int k = 0, l = 0;
 
        // Iterate and segregate big and
        // small elements
        for (int i = 0; i < N; i++) {
            if (arr[i] > K) {
                big[++k] = arr[i];
            }
            else {
                small[++l] = arr[i];
            }
        }
 
        // If k = 0, return the sum
        // of small[]
        if (k == 0) {
            int sum = 0;
            for (int i = 1; i <= N; i++) {
                sum += small[i];
            }
            return sum;
        }
 
        // Prefix sums of small[]
        // and big[]
        calc(big, k);
        calc(small, l);
 
        // Initialize small[l] within the range
        // fill(small + l + 1, small + N + 1, small[l]);
        for (int i = l + 1; i <= N; i++) {
            small[i] = small[l];
        }
 
        // Variable to store the answer
        int res = 0;
        for (int i = (k + X) / (1 + X); i <= k; i++) {
            if (1 * (i - 1) * (X + 1) + 1 <= N) {
 
                // Update res with maximum one
                res = Math.Max(
                    res,
                    big[i]
                        + small[N - 1 * (i - 1) * (X + 1)
                                - 1]);
            }
        }
 
        // Return res
        return res;
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
        int[] arr = { 9, 13, 16, 21, 6 };
        int X = 2;
        int K = 15;
        int N = arr.Length;
 
        Console.WriteLine(maxScore(arr, X, K, N));
    }
}
 
// This code is contributed by ukasp.


Javascript


输出
50

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