通过将两个元素替换为任意索引的总和最多 K 次来最小化减少数组的成本
给定一个大小为N的数组arr[]和一个整数K 。任务是找到收集数组总和所需的最小成本。通过选择任何元素并将其添加到数组中任何索引的元素来收集数组的总和。最多允许在同一索引处添加元素K次。
例子:
Input: arr[] = {3, 6, 4, 1, 1}, N = 5, K = 2
Output: 11
Explanation: Sum of the array can be collected as follows:
- Pick element at index 4 and add it to element at index 2 i.e (1 ⇢ 4) = 1+4 = 5, cost = 1 and arr[] = {3, 6, 5, 1, 0}.
- Pick element at index 3 and add it to element at index 2 i.e (1 ⇢ 5) = 1+5 = 6, cost = 1+1 = 2 and arr[] = {3, 6, 6, 0, 0}.
- Pick element at index 0 and add it to element at index 1 i.e (3 ⇢ 6) = 3+6 = 9, cost = 2+3 = 5 and arr[] = {0, 9, 6, 0, 0}.
- Pick element at index 2 and add it to element at index 1 i.e (6 ⇢ 9) = 6+9 = 15, cost = 5+6 = 11 and arr[] = {0, 15, 0, 0, 0}.
Input: arr[] = {5, 3, 2, 1, 4, 6}, N = 6, K = 3
Output: 18
Explanation: Sum can be collected as follows
- Pick element at index 3 and add it to element at index 4 i.e (1 ⇢ 4) = 1+4 = 5, cost = 1 and arr[] = {5, 3, 2, 0, 5, 6}.
- Pick element at index 2 and add it to element at index 0 i.e (2 ⇢ 5) = 2+5 = 7, cost = 1+2 = 3 and arr[] = {7, 3, 0, 0, 5, 6}.
- Pick element at index 1 and add it to element at index 5 i.e (3 ⇢ 6) = 3+6 = 9, cost = 3+3 = 6 and arr[] = {7, 0, 0, 0, 5, 9}.
- Pick element at index 4 and add it to element at index 5 i.e (5 ⇢ 9) = 5+9 = 14, cost = 6+5 = 11 and arr[] = {7, 0, 0, 0, 0, 14}.
- Pick element at index 0 and add it to element at index 5 i.e (7 ⇢ 14) = 7+14 = 21, cost = 11+7 = 18 and arr[] = {0, 0, 0, 0, 0, 21}.
方法:给定的问题可以使用贪心方法来解决。这个想法是对数组进行排序。以下对问题的解释:给定的元素是图的顶点。操作 ⇢ 将一个元素添加到其他 ⇢ 更改将一个顶点的子树悬挂到另一个顶点的操作。
任务是获得这样的树配置,每个顶点有不超过 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)