📌  相关文章
📜  通过将两个元素替换为任意索引的总和最多 K 次来最小化减少数组的成本

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

通过将两个元素替换为任意索引的总和最多 K 次来最小化减少数组的成本

给定一个大小为N的数组arr[]和一个整数K 。任务是找到收集数组总和所需的最小成本。通过选择任何元素并将其添加到数组中任何索引的元素来收集数组的总和。最多允许在同一索引处添加元素K次。

例子:

方法:给定的问题可以使用贪心方法来解决。这个想法是对数组进行排序。以下对问题的解释:给定的元素是图的顶点。操作 ⇢ 将一个元素添加到其他 ⇢ 更改将一个顶点的子树悬挂到另一个顶点的操作。

任务是获得这样的树配置,每个顶点有不超过 K 个子树挂在它上面,并且写在顶点上的数字乘积之和以及顶点的深度(其中根的深度为 0)是最小的。为了最小化总和:

  • 具有较大数量的顶点不能比具有较小数量的顶点具有更多的深度(否则可以更改它们并获得更少的总和)。
  • 每个内部顶点,除此之外,可能有一个,正好有 k 个后继。 (在实际实现中,不需要建树,我们只需要知道这是一棵树。)

现在计算此配置的总和。为了做到这一点,请按照以下步骤操作:

  • 添加到从第 1 到第 k 个元素的答案总和(在 0 索引数组中,按非递增顺序排序),乘以 1 ;然后是下 k 个桩的大小之和,乘以 2;依此类推,直到数组结束。
  • 要获得关于段总和的答案,请在对数组进行排序后使用前缀总和

下面是上述方法的实现:

C++
// C++ implementation for the above approach
 
#include 
using namespace std;
 
// Function to return the difference
// of the elements in a range
int sum(int s[], int l, int r, int N)
{
 
    r = min(r, (N - 1));
 
    return s[r] - s[l - 1];
}
 
// Function to find the minimum cost required
// to collect the sum of the array
int minCost(int arr[], int K, int N)
{
 
    int s[N];
 
    // Sort the array in descending order
    sort(arr, arr + N, greater());
 
    s[0] = arr[0];
 
    // Traverse and store the sums
    // in prefix array s[]
    for (int i = 1; i < N; i++)
        s[i] = s[i - 1] + arr[i];
 
    int res_1 = 0;
 
    // Iterate the array and add the
    // value of the element
    // multiplied by its index
    for (int i = 1; i < N; i++)
        res_1 += arr[i] * i;
 
    // If K = 1 return res_1
    if (K == 1)
        return res_1;
 
    // Variable to store the answer
    int res = 0, sz = 1;
 
    // Traverse and find the
    // answer accordingly
    for (int j = 1, t = 1; j < N; j += sz, t++) {
 
        sz *= K;
        res += sum(s, j, j + sz - 1, N) * t;
    }
 
    // Return res
    return res;
}
 
// Driver Code
int main()
{
 
    // Initialize the array
    int arr[] = { 3, 6, 4, 1, 1 };
 
    int K = 2;
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Call the function and
    // print the answer
    cout << minCost(arr, K, N);
 
    return 0;
}


Java
// Java code for the above approach
import java.util.Arrays;
import java.util.Collections;
class GFG {
 
    // Function to return the difference
    // of the elements in a range
    static int sum(int s[], int l, int r, int N)
    {
 
        r = Math.min(r, (N - 1));
 
        return s[r] - s[l - 1];
    }
 
    // Function to find the minimum cost required
    // to collect the sum of the array
    static int minCost(int arr[], int K, int N)
    {
 
        int[] s = new int[N];
 
        // Sort the array in descending order
        // Sorting the array in ascending order
        Arrays.sort(arr);
 
        // Reversing the array
        reverse(arr);
 
        s[0] = arr[0];
 
        // Traverse and store the sums
        // in prefix array s[]
        for (int i = 1; i < N; i++)
            s[i] = s[i - 1] + arr[i];
 
        int res_1 = 0;
 
        // Iterate the array and add the
        // value of the element
        // multiplied by its index
        for (int i = 1; i < N; i++)
            res_1 += arr[i] * i;
 
        // If K = 1 return res_1
        if (K == 1)
            return res_1;
 
        // Variable to store the answer
        int res = 0, sz = 1;
 
        // Traverse and find the
        // answer accordingly
        for (int j = 1, t = 1; j < N; j += sz, t++) {
 
            sz *= K;
            res += sum(s, j, j + sz - 1, N) * t;
        }
 
        // Return res
        return res;
    }
    public static void reverse(int[] array)
    {
 
        // Length of the array
        int n = array.length;
 
        // Swaping the first half elements with last half
        // elements
        for (int i = 0; i < n / 2; i++) {
 
            // Storing the first half elements temporarily
            int temp = array[i];
 
            // Assigning the first half to the last half
            array[i] = array[n - i - 1];
 
            // Assigning the last half to the first half
            array[n - i - 1] = temp;
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
       
        // Initialize the array
        int arr[] = { 3, 6, 4, 1, 1 };
 
        int K = 2;
        int N = arr.length;
 
        // Call the function and
        // print the answer
 
        System.out.println(minCost(arr, K, N));
    }
}
 
// This code is contributed by Potta Lokesh


Python3
# Python implementation for the above approach
 
# Function to return the difference
# of the elements in a range
def sum (s, l, r, N):
    r = min(r, (N - 1))
    return s[r] - s[l - 1]
 
# Function to find the minimum cost required
# to collect the sum of the array
def minCost (arr, K, N):
 
    s = [0] * N
 
    # Sort the array in descending order
    arr = sorted(arr, reverse=True)
 
    s[0] = arr[0]
 
    # Traverse and store the sums
    # in prefix array s[]
    for i in range(1, N):
        s[i] = s[i - 1] + arr[i]
 
    res_1 = 0
 
    # Iterate the array and add the
    # value of the element
    # multiplied by its index
    for i in range(1, N):
        res_1 += arr[i] * i
 
    # If K = 1 return res_1
    if (K == 1):
        return res_1
 
    # Variable to store the answer
    res = 0
    sz = 1
 
    # Traverse and find the
    # answer accordingly
    j=1
    t=1
 
    while(j < N ):
        sz *= K
        res += sum(s, j, j + sz - 1, N) * t
        j += sz
        t += 1
     
 
    # Return res
    return res
 
# Driver Code
 
# Initialize the array
arr = [3, 6, 4, 1, 1]
 
K = 2
N = len(arr)
 
# Call the function and
# print the answer
print(minCost(arr, K, N))
 
# This code is contributed by Saurabh Jaiswal


C#
// C# code for the above approach
using System;
 
public class GFG {
 
    // Function to return the difference
    // of the elements in a range
    static int sum(int []s, int l, int r, int N)
    {
 
        r = Math.Min(r, (N - 1));
 
        return s[r] - s[l - 1];
    }
 
    // Function to find the minimum cost required
    // to collect the sum of the array
    static int minCost(int []arr, int K, int N)
    {
 
        int[] s = new int[N];
 
        // Sort the array in descending order
        // Sorting the array in ascending order
        Array.Sort(arr);
 
        // Reversing the array
        reverse(arr);
 
        s[0] = arr[0];
 
        // Traverse and store the sums
        // in prefix array s[]
        for (int i = 1; i < N; i++)
            s[i] = s[i - 1] + arr[i];
 
        int res_1 = 0;
 
        // Iterate the array and add the
        // value of the element
        // multiplied by its index
        for (int i = 1; i < N; i++)
            res_1 += arr[i] * i;
 
        // If K = 1 return res_1
        if (K == 1)
            return res_1;
 
        // Variable to store the answer
        int res = 0, sz = 1;
 
        // Traverse and find the
        // answer accordingly
        for (int j = 1, t = 1; j < N; j += sz, t++) {
 
            sz *= K;
            res += sum(s, j, j + sz - 1, N) * t;
        }
 
        // Return res
        return res;
    }
    public static void reverse(int[] array)
    {
 
        // Length of the array
        int n = array.Length;
 
        // Swaping the first half elements with last half
        // elements
        for (int i = 0; i < n / 2; i++) {
 
            // Storing the first half elements temporarily
            int temp = array[i];
 
            // Assigning the first half to the last half
            array[i] = array[n - i - 1];
 
            // Assigning the last half to the first half
            array[n - i - 1] = temp;
        }
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
       
        // Initialize the array
        int []arr = { 3, 6, 4, 1, 1 };
 
        int K = 2;
        int N = arr.Length;
 
        // Call the function and
        // print the answer
 
        Console.WriteLine(minCost(arr, K, N));
    }
}
 
// This code is contributed by 29AjayKumar


Javascript


输出
11

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