Minimize cost of operation to equalize tower heights
Last Updated :
19 Sep, 2023
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[] = {7,1,5 };
cost[] = { 1, 1, 1 };
Output : 6
abs(7-5) + abs(1-5) + abs(5-5) = 6 (taking 5
as final height)
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.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
long int costOfOperation( int n, int h[], int cost[],
int eq_h)
{
long int c = 0;
for ( int i = 0; i < n; i++)
c += abs (h[i] - eq_h) * cost[i];
return c;
}
long long int Bsearch( int n, int h[], int cost[])
{
long int max_h = *max_element(h, h + n);
long int ans = LONG_MAX;
long int high = 1 + max_h;
long int low = 0;
while (high > low) {
int mid = (low + high) >> 1;
long int bm = (mid > 0) ?
costOfOperation(n, h, cost, mid - 1) :
LONG_MAX;
long int m = costOfOperation(n, h, cost, mid);
long int am = costOfOperation(n, h, cost, mid + 1);
ans = min(ans, m);
if (bm <= m)
high = mid;
else if (am <= m)
low = mid + 1;
else
return m;
}
return ans;
}
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;
}
|
Java
import java.util.Arrays;
public class MinCostOp_Mintowerheight {
static long costOfOperation( int n, int h[], int cost[],
int eq_h)
{
long c = 0 ;
for ( int i = 0 ; i < n; i++)
c += Math.abs(h[i] - eq_h) * cost[i];
return c;
}
static long Bsearch( int n, int h[], int cost[])
{
int max_h = Arrays.stream(h).max().getAsInt();
long ans = Long.MAX_VALUE;
long high = 1 + max_h;
long low = 0 ;
while (high > low) {
int mid = ( int ) ((low + high) >> 1 );
long bm = (mid > 0 ) ?
costOfOperation(n, h, cost, mid - 1 ) :
Long.MAX_VALUE;
long m = costOfOperation(n, h, cost, mid);
long am = costOfOperation(n, h, cost, mid + 1 );
if (ans == m)
break ;
ans = Long.min(ans, m);
if (bm <= m)
high = mid;
else if (am <= m)
low = mid + 1 ;
else
return m;
}
return ans;
}
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));
}
}
|
Python3
import sys
def costOfOperation(n, h,cost, eq_h):
c = 0
for i in range ( 0 , n, 1 ):
c + = abs (h[i] - eq_h) * cost[i]
return c
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
high = 1 + max_h
low = 0
while (high > low):
mid = (low + high) >> 1
if (mid > 0 ):
bm = costOfOperation(n, h, cost, mid - 1 )
else :
bm = sys.maxsize
m = costOfOperation(n, h, cost, mid)
am = costOfOperation(n, h, cost, mid + 1 )
if (ans = = m):
break
ans = min (ans, m)
if (bm < = m):
high = mid
else if (am < = m):
low = mid + 1
else :
return m;
return ans
if __name__ = = '__main__' :
h = [ 1 , 2 , 3 ]
cost = [ 10 , 100 , 1000 ]
n = len (h)
print (Bsearch(n, h, cost))
|
C#
using System;
using System.Linq;
public class MinCostOp_Mintowerheight
{
static long costOfOperation( int n, int []h,
int []cost, int eq_h)
{
long c = 0;
for ( int i = 0; i < n; i++)
c += Math.Abs(h[i] - eq_h) * cost[i];
return c;
}
static long Bsearch( int n, int []h, int []cost)
{
int max_h = h.Max();
long ans = long .MaxValue;
long high = 1 + max_h;
long low = 0;
while (high > low)
{
int mid = ( int ) ((low + high) >> 1);
long bm = (mid > 0) ?
costOfOperation(n, h, cost, mid - 1) :
long .MaxValue;
long m = costOfOperation(n, h, cost, mid);
long am = costOfOperation(n, h, cost, mid + 1);
if (ans == m)
break ;
ans = Math.Min(ans, m);
if (bm <= m)
high = mid;
else if (am <= m)
low = mid + 1;
else
return m;
}
return ans;
}
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));
}
}
|
PHP
<?php
function costOfOperation( $n , $h , $cost , $eq_h )
{
$c = 0;
for ( $i = 0; $i < $n ; $i ++)
$c += abs ( $h [ $i ] - $eq_h ) * $cost [ $i ];
return $c ;
}
function Bsearch( $n , $h , $cost )
{
$max_h = max( $h );
$ans = PHP_INT_MAX;
$high = 1 + $max_h ;
$low = 0;
while ( $high > $low )
{
$mid = ( $low + $high ) >> 1;
$bm = ( $mid > 0) ?
costOfOperation( $n , $h , $cost , $mid - 1) :
PHP_INT_MAX;
$m = costOfOperation( $n , $h , $cost , $mid );
$am = costOfOperation( $n , $h , $cost , $mid + 1);
if ( $ans == $m )
break ;
$ans = min( $ans , $m );
if ( $bm <= $m )
$high = $mid ;
else if ( $am <= $m )
$low = $mid + 1;
else
return $m ;
}
return $ans ;
}
$h = array ( 1, 2, 3 );
$cost = array ( 10, 100, 1000 );
$n = count ( $h );
echo Bsearch( $n , $h , $cost );
?>
|
Javascript
<script>
function costOfOperation(n, h, cost, eq_h)
{
let c = 0;
for (let i = 0; i < n; i++)
c += Math.abs(h[i] - eq_h) * cost[i];
return c;
}
function Bsearch(n, h, cost)
{
let max_h = [...h].sort((a, b) => a - b)[h.length - 1];
let ans = Number.MAX_SAFE_INTEGER;
let high = 1 + max_h;
let low = 0;
while (high > low)
{
let mid = (low + high) >> 1;
let bm = (mid > 0) ?
costOfOperation(n, h, cost, mid - 1) :
PHP_INT_MAX;
let m = costOfOperation(n, h, cost, mid);
let am = costOfOperation(n, h, cost, mid + 1);
if (ans == m)
break ;
ans = Math.min(ans, m);
if (bm <= m)
high = mid;
else if (am <= m)
low = mid + 1;
else
return m;
}
return ans;
}
let h = new Array( 1, 2, 3 );
let cost = new Array( 10, 100, 1000 );
let n = h.length;
document.write(Bsearch(n, h, cost));
</script>
|
Time Complexity: O(n*log(max_h)), where n is the size of the given array and max_h is the maximum element in the array.
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...