Open In App

Minimize the Sum of Absolute Costs of an Array Optimally

Last Updated : 18 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of costs, your task is to minimize the sum of the absolute differences between consecutive costs by performing following operation at most once. Operation is that, we can select any index ‘i’ then make arr[i] = arr[i]/2.

Example:

Input: arr= [4,9,8]
Output: 4
Explanation: At index 0, 4 is halved now the array looks like = [2,9,8] and sum of absolute difference is abs(2-abs (9-8)= 8
At index 1, 9 is halved now the array looks like =[4,4,8] and sum of absolute difference is abs(4-abs (4-8)= 4
At index 2 8 is halved now the array looks like = [4,9,4] and sum of absolute difference is abs(4-abs (9-4)= 10
minimum of all absolute sums is 4.

Input: arr= [99,102,1,45,65]
Output: 161
Explanation: At index 0, 99 is halved now the array looks like = [49,102,1,45,65] and sum of absolute difference is 218
At index 1, 102 is halved now the array looks like = [99,51,1,45,65] and sum of absolute difference is 162
At index 2, 1 is halved now the array looks like = [99,102,0,45,65] and sum of absolute difference is 170
At index 3, 45 is halved now the array looks like = [99,102,1,22,65] and sum of absolute difference is 168
At index 4, 65 is halved now the array looks like = [99,102,1,45,32] and sum of absolute difference is 161

Approach:

We can solve this problem by just iterating the elements of an array and apply the operation on the element and store the minimum answer in any variable, this minimum value will be our resultant answer.

Steps to solve this problem:

  1. arr: The input array containing the costs.
  2. abs_arr: An array to store the absolute differences between consecutive costs.
  3. min_sum: A variable to keep track of the minimum sum of absolute differences. Initialize it with positive infinity to ensure it gets updated.
  4. Calculate the absolute differences between consecutive costs and store them in abs_arr. The first and last elements are initialized with 0 because they don’t have a previous or next element to compare with.
  5. Calculate the sum of the absolute differences and store it in the variable s.
  6. Iterate through each element of the arr array, considering the cost reductions for each element:
  7. If i-1 is less than 0, this means there is no previous element, so left_sum is set to 0.
  8. If i+1 is greater than the last index, this means there is no next element, so right_sum is set to 0.
  9. Otherwise, calculate left_sum as the absolute difference between the cost halved and the previous cost, and right_sum as the absolute difference between the cost halved and the next cost.
  10. Calculate the total sum of left_sum and right_sum for the current element. Calculate the sum_sofar as the total sum, including total, minus the absolute differences at the current and next elements (subtracting abs_arr[i] and abs_arr[i+1]).
  11. Update min_sum by taking the minimum of the current min_sum and sum_sofar. This tracks the minimum sum of absolute differences observed so far.
  12. After iterating through all elements in the array, min_sum will contain the minimum sum of absolute differences that can be achieved with the given cost reductions.
  13. Print the value of min_sum, which represents the minimum sum of absolute differences between consecutive costs.

Below is the implementation of the above problem:

C++




// C++ Implementation
#include <iostream>
#include <vector>
#include <cmath>
#include <limits>
 
using namespace std;
 
int minimize_absolute_differences(vector<int>& arr) {
    // Create a vector to store the absolute differences between consecutive costs.
    vector<int> abs_arr(arr.size() + 1, 0);
 
    // Initialize a variable to store the minimum sum of absolute differences.
    int min_sum = numeric_limits<int>::max();
 
    // Calculate the absolute differences between consecutive costs and store them in abs_arr.
    for (int i = 1; i < arr.size(); ++i) {
        abs_arr[i] = abs(arr[i] - arr[i - 1]);
    }
 
    // Set the last element of abs_arr to 0 because there's no next element to compare.
    abs_arr[arr.size()] = 0;
 
    // Calculate the sum of absolute differences.
    int s = 0;
    for (int val : abs_arr) {
        s += val;
    }
 
    // Iterate through each element in the input array.
    for (int i = 0; i < arr.size(); ++i) {
        int left_sum, right_sum;
 
        if (i - 1 < 0) {
            left_sum = 0;
            right_sum = abs(floor(arr[i] / 2.0) - arr[i + 1]);
        } else if (i + 1 > arr.size() - 1) {
            right_sum = 0;
            left_sum = abs(floor(arr[i] / 2.0) - arr[i - 1]);
        } else {
            left_sum = abs(floor(arr[i] / 2.0) - arr[i - 1]);
            right_sum = abs(floor(arr[i] / 2.0) - arr[i + 1]);
        }
 
        int total = left_sum + right_sum;
        int sum_sofar = s + total - (abs_arr[i] + abs_arr[i + 1]);
 
        min_sum = min(min_sum, sum_sofar);
    }
 
    // Return the minimum sum of absolute differences.
    return min_sum;
}
 
int main() {
    vector<int> arr = {99, 102, 1, 45, 65};
    int result = minimize_absolute_differences(arr);
    cout << result << endl;
    return 0;
}
 
// This code is contributed by Tapesh(tapeshdua420)


Java




import java.util.Arrays;
 
public class MinimizeAbsoluteDifferences {
 
    public static int minimizeAbsoluteDifferences(int[] arr) {
        // Create an array to store the absolute differences between consecutive costs.
        int[] absArr = new int[arr.length + 1];
 
        // Initialize a variable to store the minimum sum of absolute differences.
        int minSum = Integer.MAX_VALUE;
 
        // Calculate the absolute differences between consecutive costs and store them in absArr.
        for (int i = 1; i < arr.length; i++) {
            absArr[i] = Math.abs(arr[i] - arr[i - 1]);
        }
 
        // Set the last element of absArr to 0 because there's no next element to compare.
        absArr[arr.length] = 0;
 
        // Calculate the sum of absolute differences.
        int s = Arrays.stream(absArr).sum();
 
        // Iterate through each element in the input array.
        for (int i = 0; i < arr.length; i++) {
            int leftSum, rightSum;
 
            if (i - 1 < 0) {
                // If there's no previous element, set leftSum to 0.
                leftSum = 0;
                // Calculate the absolute difference between the cost halved and the next cost.
                rightSum = Math.abs((int) Math.floor(arr[i] / 2.0) - arr[i + 1]);
            } else if (i + 1 > arr.length - 1) {
                // If there's no next element, set rightSum to 0.
                rightSum = 0;
                // Calculate the absolute difference between the cost halved and the previous cost.
                leftSum = Math.abs((int) Math.floor(arr[i] / 2.0) - arr[i - 1]);
            } else {
                // Calculate the absolute difference between the cost halved and the previous cost.
                leftSum = Math.abs((int) Math.floor(arr[i] / 2.0) - arr[i - 1]);
                // Calculate the absolute difference between the cost halved and the next cost.
                rightSum = Math.abs((int) Math.floor(arr[i] / 2.0) - arr[i + 1]);
            }
 
            // Calculate the total sum of leftSum and rightSum.
            int total = leftSum + rightSum;
 
            // Calculate the sum so far, including total, minus the absolute differences at the current and next elements.
            int sumSoFar = s + total - (absArr[i] + absArr[i + 1]);
 
            // Update the minimum sum with the minimum of the current sumSoFar and the previous minimum.
            minSum = Math.min(minSum, sumSoFar);
        }
 
        // Return the minimum sum of absolute differences.
        return minSum;
    }
 
    public static void main(String[] args) {
        int[] arr = {99, 102, 1, 45, 65};
        int result = minimizeAbsoluteDifferences(arr);
        System.out.println(result);
    }
}


Python




import math
 
 
def minimize_absolute_differences(arr):
    # Create an array to store the absolute differences between consecutive costs.
    abs_arr = [0]
 
    # Initialize a variable to store the minimum sum of absolute differences.
    min_sum = float('inf')
 
    # Calculate the absolute differences between consecutive costs and store them in abs_arr.
    for i in range(1, len(arr)):
        abs_arr.append(abs(arr[i] - arr[i - 1]))
 
    # Set the last element of abs_arr to 0 because there's no next element to compare.
    abs_arr.append(0)
 
    # Calculate the sum of absolute differences.
    s = sum(abs_arr)
 
    # Iterate through each element in the input array.
    for i in range(len(arr)):
        if i - 1 < 0:
            # If there's no previous element, set left_sum to 0.
            left_sum = 0
            # Calculate the absolute difference between the cost halved and the next cost.
            right_sum = abs(math.floor(arr[i] / 2) - arr[i + 1])
        elif i + 1 > len(arr) - 1:
            # If there's no next element, set right_sum to 0.
            right_sum = 0
            # Calculate the absolute difference between the cost halved and the previous cost.
            left_sum = abs(math.floor(arr[i] / 2) - arr[i - 1])
        else:
            # Calculate the absolute difference between the cost halved and the previous cost.
            left_sum = abs(math.floor(arr[i] / 2) - arr[i - 1])
            # Calculate the absolute difference between the cost halved and the next cost.
            right_sum = abs(math.floor(arr[i] / 2) - arr[i + 1])
 
        # Calculate the total sum of left_sum and right_sum.
        total = left_sum + right_sum
 
        # Calculate the sum so far, including total, minus the absolute differences at the current and next elements.
        sum_sofar = s + total - (abs_arr[i] + abs_arr[i + 1])
 
        # Update the minimum sum with the minimum of the current sum_sofar and the previous minimum.
        min_sum = min(min_sum, sum_sofar)
 
    # Return the minimum sum of absolute differences.
    return min_sum
 
 
arr = [99, 102, 1, 45, 65]
result = minimize_absolute_differences(arr)
print(result)


C#




using System;
using System.Collections.Generic;
 
class Program
{
    static int MinimizeAbsoluteDifferences(List<int> arr)
    {
        // Create a list to store the absolute differences between consecutive costs.
        List<int> absArr = new List<int>(arr.Count);
 
        // Initialize a variable to store the minimum sum of absolute differences.
        int minSum = int.MaxValue;
 
        // Calculate the absolute differences between consecutive costs and store them in absArr.
        for (int i = 1; i < arr.Count; i++)
        {
            absArr.Add(Math.Abs(arr[i] - arr[i - 1]));
        }
 
        // Calculate the sum of absolute differences.
        int sum = 0;
        foreach (int val in absArr)
        {
            sum += val;
        }
 
        // Iterate through each element in the input array.
        for (int i = 0; i < arr.Count; i++)
        {
            int leftSum = 0, rightSum = 0;
 
            if (i > 0)
            {
                leftSum = Math.Abs((int)Math.Floor(arr[i] / 2.0) - arr[i - 1]);
            }
 
            if (i < arr.Count - 1)
            {
                rightSum = Math.Abs((int)Math.Floor(arr[i] / 2.0) - arr[i + 1]);
            }
 
            int total = leftSum + rightSum;
            int sumSoFar = sum +
              total - (i > 0 ? absArr[i - 1] : 0) - (i < arr.Count - 1 ? absArr[i] : 0);
 
            minSum = Math.Min(minSum, sumSoFar);
        }
 
        // Return the minimum sum of absolute differences.
        return minSum;
    }
 
    static void Main(string[] args)
    {
        List<int> arr = new List<int> { 99, 102, 1, 45, 65 };
        int result = MinimizeAbsoluteDifferences(arr);
        Console.WriteLine(result);
    }
}
 
// This code is contributed by akshitaguprzj3


Javascript




function minimizeAbsoluteDifferences(arr) {
    // Create an array to store the absolute
    // differences between consecutive costs.
    let absArr = [0];
 
    // Initialize a variable to store the
    // minimum sum of absolute differences.
    let minSum = Infinity;
 
    // Calculate the absolute differences between
    // consecutive costs and store them in absArr.
    for (let i = 1; i < arr.length; i++) {
        absArr.push(Math.abs(arr[i] - arr[i - 1]));
    }
 
    // Set the last element of absArr to 0 because
    // there's no next element to compare.
    absArr.push(0);
 
    // Calculate the sum of absolute differences.
    let s = absArr.reduce((acc, val) => acc + val, 0);
 
    // Iterate through each element in the input array.
    for (let i = 0; i < arr.length; i++) {
        let leftSum, rightSum;
 
        if (i - 1 < 0) {
            // If there's no previous element, set leftSum to 0.
            leftSum = 0;
            // Calculate the absolute difference
            // between the cost halved and the next cost.
            rightSum = Math.abs(Math.floor(arr[i] / 2) - arr[i + 1]);
        }
        else if (i + 1 > arr.length - 1) {
            // If there's no next element, set rightSum to 0.
            rightSum = 0;
            // Calculate the absolute difference between
            // the cost halved and the previous cost.
            leftSum = Math.abs(Math.floor(arr[i] / 2) - arr[i - 1]);
        }
        else {
            // Calculate the absolute difference between
            // the cost halved and the previous cost.
            leftSum = Math.abs(Math.floor(arr[i] / 2) - arr[i - 1]);
            // Calculate the absolute difference between
            // the cost halved and the next cost.
            rightSum = Math.abs(Math.floor(arr[i] / 2) - arr[i + 1]);
        }
 
        // Calculate the total sum of leftSum and rightSum.
        let total = leftSum + rightSum;
 
        // Calculate the sum so far, including total,
        // minus the absolute differences at the current and next elements.
        let sumSoFar = s + total - (absArr[i] + absArr[i + 1]);
 
        // Update the minimum sum with the minimum of
        // the current sumSoFar and the previous minimum.
        minSum = Math.min(minSum, sumSoFar);
    }
 
    // Return the minimum sum of absolute differences.
    return minSum;
}
 
let arr = [99, 102, 1, 45, 65];
let result = minimizeAbsoluteDifferences(arr);
console.log(result);


Output

161

Time Complexity: O(n)
Auxiliary space: O(n)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads