Minimize cost for reducing array by replacing two elements with sum at most K times for any index
Given an array arr[] of size N and an integer K. The task is to find the minimum cost required to collect the sum of the array. The sum of the array is collected by picking any element and adding it to an element of any index in the array. The addition of elements at the same index is allowed for at most K times.
Example:
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}.
Approach: The given problem can be solved using a greedy approach. The idea is to sort the array. following interpretation of the problem: given elements are the graph vertices. Operation ⇢ add one element to other ⇢ changes to operation of suspension of sub-tree of one vertices to another.
The task is to get such tree configuration, that each vertices has no more than K sub-trees suspended to it, and sum of the products of numbers, written on vertices, and vertices’ depth (where root’s depth is 0) is minimal. In order to minimize the sum:
- vertices with a larger number must not have more depth than vertices with smaller number (otherwise it’s possible to change them and to get less sum).
- each inner vertices, besides, maybe, one, has exactly k successors. (In actual implementation, there is no need to build a tree, we only need to know that this is a tree.)
Now calculate the sum for this configuration. In order do to it, follow the following steps:
- Add to answer sum of elements from 1st to kth (in 0-indexed array, sorted in non-increasing order), multiplied by 1; then sum of sizes of next k piles, multiplied by 2; and so on till the end of array.
- To get the answer about the sum of segment, use prefix sum after sorting the array.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int sum( int s[], int l, int r, int N)
{
r = min(r, (N - 1));
return s[r] - s[l - 1];
}
int minCost( int arr[], int K, int N)
{
int s[N];
sort(arr, arr + N, greater< int >());
s[0] = arr[0];
for ( int i = 1; i < N; i++)
s[i] = s[i - 1] + arr[i];
int res_1 = 0;
for ( int i = 1; i < N; i++)
res_1 += arr[i] * i;
if (K == 1)
return res_1;
int res = 0, sz = 1;
for ( int j = 1, t = 1; j < N; j += sz, t++) {
sz *= K;
res += sum(s, j, j + sz - 1, N) * t;
}
return res;
}
int main()
{
int arr[] = { 3, 6, 4, 1, 1 };
int K = 2;
int N = sizeof (arr) / sizeof (arr[0]);
cout << minCost(arr, K, N);
return 0;
}
|
Java
import java.util.Arrays;
import java.util.Collections;
class GFG {
static int sum( int s[], int l, int r, int N)
{
r = Math.min(r, (N - 1 ));
return s[r] - s[l - 1 ];
}
static int minCost( int arr[], int K, int N)
{
int [] s = new int [N];
Arrays.sort(arr);
reverse(arr);
s[ 0 ] = arr[ 0 ];
for ( int i = 1 ; i < N; i++)
s[i] = s[i - 1 ] + arr[i];
int res_1 = 0 ;
for ( int i = 1 ; i < N; i++)
res_1 += arr[i] * i;
if (K == 1 )
return res_1;
int res = 0 , sz = 1 ;
for ( int j = 1 , t = 1 ; j < N; j += sz, t++) {
sz *= K;
res += sum(s, j, j + sz - 1 , N) * t;
}
return res;
}
public static void reverse( int [] array)
{
int n = array.length;
for ( int i = 0 ; i < n / 2 ; i++) {
int temp = array[i];
array[i] = array[n - i - 1 ];
array[n - i - 1 ] = temp;
}
}
public static void main(String[] args)
{
int arr[] = { 3 , 6 , 4 , 1 , 1 };
int K = 2 ;
int N = arr.length;
System.out.println(minCost(arr, K, N));
}
}
|
Python3
def sum (s, l, r, N):
r = min (r, (N - 1 ))
return s[r] - s[l - 1 ]
def minCost (arr, K, N):
s = [ 0 ] * N
arr = sorted (arr, reverse = True )
s[ 0 ] = arr[ 0 ]
for i in range ( 1 , N):
s[i] = s[i - 1 ] + arr[i]
res_1 = 0
for i in range ( 1 , N):
res_1 + = arr[i] * i
if (K = = 1 ):
return res_1
res = 0
sz = 1
j = 1
t = 1
while (j < N ):
sz * = K
res + = sum (s, j, j + sz - 1 , N) * t
j + = sz
t + = 1
return res
arr = [ 3 , 6 , 4 , 1 , 1 ]
K = 2
N = len (arr)
print (minCost(arr, K, N))
|
C#
using System;
public class GFG {
static int sum( int []s, int l, int r, int N)
{
r = Math.Min(r, (N - 1));
return s[r] - s[l - 1];
}
static int minCost( int []arr, int K, int N)
{
int [] s = new int [N];
Array.Sort(arr);
reverse(arr);
s[0] = arr[0];
for ( int i = 1; i < N; i++)
s[i] = s[i - 1] + arr[i];
int res_1 = 0;
for ( int i = 1; i < N; i++)
res_1 += arr[i] * i;
if (K == 1)
return res_1;
int res = 0, sz = 1;
for ( int j = 1, t = 1; j < N; j += sz, t++) {
sz *= K;
res += sum(s, j, j + sz - 1, N) * t;
}
return res;
}
public static void reverse( int [] array)
{
int n = array.Length;
for ( int i = 0; i < n / 2; i++) {
int temp = array[i];
array[i] = array[n - i - 1];
array[n - i - 1] = temp;
}
}
public static void Main(String[] args)
{
int []arr = { 3, 6, 4, 1, 1 };
int K = 2;
int N = arr.Length;
Console.WriteLine(minCost(arr, K, N));
}
}
|
Javascript
<script>
const sum = (s, l, r, N) => {
r = Math.min(r, (N - 1));
return s[r] - s[l - 1];
}
const minCost = (arr, K, N) => {
let s = new Array(N).fill(0);
arr.sort((a, b) => b - a);
s[0] = arr[0];
for (let i = 1; i < N; i++)
s[i] = s[i - 1] + arr[i];
let res_1 = 0;
for (let i = 1; i < N; i++)
res_1 += arr[i] * i;
if (K == 1)
return res_1;
let res = 0, sz = 1;
for (let j = 1, t = 1; j < N; j += sz, t++) {
sz *= K;
res += sum(s, j, j + sz - 1, N) * t;
}
return res;
}
let arr = [3, 6, 4, 1, 1];
let K = 2;
let N = arr.length
document.write(minCost(arr, K, N));
</script>
|
Time Complexity: O(N* log N)
Auxiliary Space: O(N)
Last Updated :
03 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...