Minimize cost of operation to equalize tower heights

Given heights of n (n <=10000) towers as an array h[]; we need to bring every tower to same height by either adding or removing blocks in a tower. Every addition or removal operation costs a different value in a different tower. The objective is to minimize this cost.

Examples:

Input : Tower heights h[] = {1, 2, 3}
Costs of operations cost[] = {10, 100, 1000}
Output : 120
The heights can be equalized by either "Removing 
one block from 3 and adding one in 1" or "Adding
two blocks in 1 and adding one in 2". Since the 
cost of operation in tower 3 is 1000, the first
process would yield 1010 while the second one 
yields 120. Since the second process yields the
lowest cost of operation, it is the required 
output.

Input : h[] = {2, 4, 8}
        cost[] = {10, 100, 1000}
Output : 460

Naive Approach : A naive approach would be to find the cost of each and every possible operation set, and then find the minimum cost of operation. This would give O(n2) in the worst case.

Best Approach : The best approach here seems to be Binary search. We store the minimum height & alter our resultant height by a factor of 2 in each step.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to minimize the cost of operation
// to bring all towers to same height.
#include <bits/stdc++.h>
using namespace std;
  
// Returns the cost of entire operation in bringing 
// the height of all towers to equal height eq_h
long int costOfOperation(int n, int h[], int cost[],
                         int eq_h)
{
    // Initialize initial cost to 0
    long int c = 0;
  
    // Adding cost for each tower
    for (int i = 0; i < n; i++)
        c += abs(h[i] - eq_h) * cost[i];
  
    return c;
}
  
// Return the minimum possible cost of operation
// to bring all the towers of different height
// in height[0..n-1] to same height.
long long int Bsearch(int n, int h[], int cost[])
{
    long int max_h = *max_element(h, h + n);
    long int ans = LONG_MAX;
  
    // Do binary search for minimum cost
    long int high = 1 + max_h;
    long int low = 0;
    while (high > low) {
        int mid = (low + high) >> 1;
  
        // Cost below mid
        long int bm = (mid > 0) ? 
                costOfOperation(n, h, cost, mid - 1) : 
                LONG_MAX;
  
        // Cost at mid
        long int m = costOfOperation(n, h, cost, mid);
  
        // Cost above mid
        long int am = costOfOperation(n, h, cost, mid + 1);
  
        // Break if the answer becomes equal to
        // minimum cost m
        if (ans == m)
            break;
  
        // ans should hold the minimum cost of operation
        ans = min(ans, m);
  
        // Search lower cost
        if (bm <= m)
            high = mid;
  
        // Search higher cost
        else if (am <= m)
            low = mid + 1;
    }
  
    return ans;
}
  
// Driver code
int main()
{
    int h[] = { 1, 2, 3 };
    int cost[] = { 10, 100, 1000 };
    int n = sizeof(h)/sizeof(h[0]);
    cout << Bsearch(n, h, cost);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to minimize the cost of operation
// to bring all towers to same height.
import java.util.Arrays;
public class MinCostOp_Mintowerheight {
  
    // Returns the cost of entire operation in bringing 
    // the height of all towers to equal height eq_h
    static long costOfOperation(int n, int h[], int cost[],
                                                int eq_h)
    {
        // Initialize initial cost to 0
        long c = 0;
       
        // Adding cost for each tower
        for (int i = 0; i < n; i++)
            c += Math.abs(h[i] - eq_h) * cost[i];
       
        return c;
    }
       
    // Return the minimum possible cost of operation
    // to bring all the towers of different height
    // in height[0..n-1] to same height.
    static long Bsearch(int n, int h[], int cost[])
    {
        int max_h =    Arrays.stream(h).max().getAsInt();
        long ans = Long.MAX_VALUE;
       
        // Do binary search for minimum cost
        long high = 1 + max_h;
        long low = 0;
        while (high > low) {
            int mid = (int) ((low + high) >> 1);
       
            // Cost below mid
            long bm = (mid > 0) ? 
                    costOfOperation(n, h, cost, mid - 1) : 
                    Long.MAX_VALUE;
       
            // Cost at mid
            long m = costOfOperation(n, h, cost, mid);
       
            // Cost above mid
            long am = costOfOperation(n, h, cost, mid + 1);
       
            // Break if the answer becomes equal to
            // minimum cost m
            if (ans == m)
                break;
       
            // ans should hold the minimum cost of operation
            ans = Long.min(ans, m);
       
            // Search lower cost
            if (bm <= m)
                high = mid;
       
            // Search higher cost
            else if (am <= m)
                low = mid + 1;
        }
       
        return ans;
    }
       
    // Driver code
    public static void main(String args[])
    {
        int h[] = { 1, 2, 3 };
        int cost[] = { 10, 100, 1000 };
        int n = h.length;
        System.out.println(Bsearch(n, h, cost));
    }
}
// This code is contributed by Sumit Ghosh

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python 3 program to minimize the cost of 
# operation to bring all towers to same height.
import sys
  
# Returns the cost of entire operation in 
# bringing the height of all towers to
# equal height eq_h
def costOfOperation(n, h,cost, eq_h):
      
    # Initialize initial cost to 0
    c = 0
  
    # Adding cost for each tower
    for i in range(0, n, 1):
        c += abs(h[i] - eq_h) * cost[i]
  
    return c
  
# Return the minimum possible cost of 
# operation to bring all the towers of 
# different height in height[0..n-1] 
# to same height.
def Bsearch(n, h, cost):
    max_h = h[0]
    for i in range(len(h)):
        if(h[i] > max_h):
            max_h = h[i]
    ans = sys.maxsize
  
    # Do binary search for minimum cost
    high = 1 + max_h
    low = 0
    while (high > low):
        mid = (low + high) >> 1
  
        # Cost below mid
        if(mid > 0):
            bm = costOfOperation(n, h, cost, mid - 1)
  
        else:
            bm = sys.maxsize
  
        # Cost at mid
        m = costOfOperation(n, h, cost, mid)
  
        # Cost above mid
        am = costOfOperation(n, h, cost, mid + 1)
  
        # Break if the answer becomes equal 
        # to minimum cost m
        if (ans == m):
            break
  
        # ans should hold the minimum cost 
        # of operation
        ans = min(ans, m)
  
        # Search lower cost
        if (bm <= m):
            high = mid
  
        # Search higher cost
        elif(am <= m):
            low = mid + 1
  
    return ans
  
# Driver code
if __name__ == '__main__':
    h = [1, 2, 3]
    cost = [10, 100, 1000]
    n = len(h)
    print(Bsearch(n, h, cost))
      
# This code is contributed by
# Sahil_shelangia

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to minimize the 
// cost of operation to bring
// all towers to same height.
using System;
using System.Linq;
  
public class MinCostOp_Mintowerheight
{
  
    // Returns the cost of entire
    // operation in bringing the height
    // of all towers to equal height eq_h
    static long costOfOperation(int n, int []h, 
                                int []cost, int eq_h)
    {
        // Initialize initial cost to 0
        long c = 0;
      
        // Adding cost for each tower
        for (int i = 0; i < n; i++)
            c += Math.Abs(h[i] - eq_h) * cost[i];
      
        return c;
    }
      
    // Return the minimum possible
    // cost of operation to bring 
    // all the towers of different height
    // in height[0..n-1] to same height.
    static long Bsearch(int n, int []h, int []cost)
    {
        int max_h = h.Max();
        long ans = long.MaxValue;
      
        // Do binary search for minimum cost
        long high = 1 + max_h;
        long low = 0;
        while (high > low) 
        {
            int mid = (int) ((low + high) >> 1);
      
            // Cost below mid
            long bm = (mid > 0) ? 
                    costOfOperation(n, h, cost, mid - 1) : 
                    long.MaxValue;
      
            // Cost at mid
            long m = costOfOperation(n, h, cost, mid);
      
            // Cost above mid
            long am = costOfOperation(n, h, cost, mid + 1);
      
            // Break if the answer becomes
            //  equal to minimum cost m
            if (ans == m)
                break;
      
            // ans should hold the minimum 
            // cost of operation
            ans = Math.Min(ans, m);
      
            // Search lower cost
            if (bm <= m)
                high = mid;
      
            // Search higher cost
            else if (am <= m)
                low = mid + 1;
        }
      
        return ans;
    }
      
    // Driver code
    public static void Main(String []args)
    {
        int []h = { 1, 2, 3 };
        int []cost = { 10, 100, 1000 };
        int n = h.Length;
        Console.WriteLine(Bsearch(n, h, cost));
    }
}
  
// This code contributed by Rajput-Ji

chevron_right


PHP

$low)
{
$mid = ($low + $high) >> 1;

// Cost below mid
$bm = ($mid > 0) ?
costOfOperation($n, $h, $cost, $mid – 1) :
PHP_INT_MAX;

// Cost at mid
$m = costOfOperation($n, $h, $cost, $mid);

// Cost above mid
$am = costOfOperation($n, $h, $cost, $mid + 1);

// Break if the answer becomes equal to
// minimum cost m
if ($ans == $m)
break;

// ans should hold the minimum
// cost of operation
$ans = min($ans, $m);

// Search lower cost
if ($bm <= $m) $high = $mid; // Search higher cost else if ($am <= $m) $low = $mid + 1; } return $ans; } // Driver code $h = array( 1, 2, 3 ); $cost = array( 10, 100, 1000 ); $n = count($h); echo Bsearch($n, $h, $cost); // This code is contributed by mits ?>


Output:

120

This article is contributed by Raghav Jajodia. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up



Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.