Minimize the cost to make all the adjacent elements distinct in an Array

Given two integer arrays arr[] and cost[] of size N, the task is to make all adjacent elements distinct at minimum cost. cost[i] denotes the cost to increment ith element by 1.

Examples:

Input: arr[] = {2, 2, 3}, cost[] = {4, 1, 5}
Output: 2
Explanation:
The second element has minimum increment cost. Hence, increase the cost of the second element twice.
Therefore the resultant array: {2, 4, 3}

Input: arr[] = {1, 2, 3}, cost[] = {7, 8, 3}
Output: 0

Approach:



  • We can observe that there an element might need to be increased maximum twice.
  • This problem can be solved using Dynamic Programming.
  • Create a DP-table dp[][], where rows represent the elements, and columns represent the increment.
  • dp[i][j] is the minimum cost required to make ith element distinct from its adjacent elements using j increments.
  • The value of dp[i][j] can be calculated as:

    dp[i][j] = j * cost[i] + (minimum from previous element if both elements are different)

Below is the implementation of the above approach

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find the
// minimum cost required to make
// all adjacent elements disinct
  
#include <bits/stdc++.h>
using namespace std;
  
// Function that prints minimum cost required
void minimumCost(int arr[], int cost[], int N)
{
  
    // Dp-table
    vector<vector<int> > dp(N, vector<int>(3));
  
    // Base case
    // Not increasing the first element
    dp[0][0] = 0;
  
    // Increasing the first element by 1
    dp[0][1] = cost[0];
  
    // Increasing the first element by 2
    dp[0][2] = cost[0] * 2;
  
    for (int i = 1; i < N; i++) {
        for (int j = 0; j < 3; j++) {
  
            int minimum = 1e6;
  
            // Condition if current element
            // is not equal to previous
            // non-increased element
            if (j + arr[i] != arr[i - 1])
                minimum
                    = min(minimum,
                          dp[i - 1][0]);
  
            // Condition if current element
            // is not equal to previous element
            // after being increased by 1
            if (j + arr[i] != arr[i - 1] + 1)
                minimum
                    = min(minimum,
                          dp[i - 1][1]);
  
            // Condition if current element
            // is not equal to previous element
            // after being increased by 2
            if (j + arr[i] != arr[i - 1] + 2)
                minimum
                    = min(minimum,
                          dp[i - 1][2]);
  
            // Take the minimum from all cases
            dp[i][j] = j * cost[i] + minimum;
        }
    }
  
    int ans = 1e6;
  
    // Finding the minimum cost
    for (int i = 0; i < 3; i++)
        ans = min(ans, dp[N - 1][i]);
  
    // Printing the minimum cost
    // required to make all adjacent
    // elements disinct
    cout << ans << "\n";
}
  
// Driver Code
int main()
{
    int arr[] = { 1, 1, 2, 2, 3, 4 };
    int cost[] = { 3, 2, 5, 4, 2, 1 };
    int N = sizeof(arr) / sizeof(arr[0]);
  
    minimumCost(arr, cost, N);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find the minimum 
// cost required to make all 
// adjacent elements disinct
import java.util.*;
  
class GFG{
  
// Function that prints minimum cost required
static void minimumCost(int arr[], int cost[],
                        int N)
{
  
    // Dp-table
    int [][]dp = new int[N][3];
  
    // Base case
    // Not increasing the first element
    dp[0][0] = 0;
  
    // Increasing the first element by 1
    dp[0][1] = cost[0];
  
    // Increasing the first element by 2
    dp[0][2] = cost[0] * 2;
  
    for(int i = 1; i < N; i++)
    {
       for(int j = 0; j < 3; j++)
       {
          int minimum = (int) 1e6;
            
          // Condition if current element
          // is not equal to previous
          // non-increased element
          if (j + arr[i] != arr[i - 1])
              minimum = Math.min(minimum, dp[i - 1][0]);
            
          // Condition if current element
          // is not equal to previous element
          // after being increased by 1
          if (j + arr[i] != arr[i - 1] + 1)
              minimum = Math.min(minimum, dp[i - 1][1]);
            
          // Condition if current element
          // is not equal to previous element
          // after being increased by 2
          if (j + arr[i] != arr[i - 1] + 2)
              minimum = Math.min(minimum, dp[i - 1][2]);
  
          // Take the minimum from all cases
          dp[i][j] = j * cost[i] + minimum;
       }
    }
    int ans = (int) 1e6;
  
    // Finding the minimum cost
    for(int i = 0; i < 3; i++)
       ans = Math.min(ans, dp[N - 1][i]);
  
    // Printing the minimum cost
    // required to make all adjacent
    // elements disinct
    System.out.print(ans + "\n");
}
  
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 1, 1, 2, 2, 3, 4 };
    int cost[] = { 3, 2, 5, 4, 2, 1 };
    int N = arr.length;
  
    minimumCost(arr, cost, N);
}
}
  
// This code is contributed by 29AjayKumar

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to find the
# minimum cost required to make
# all adjacent elements disinct
  
# Function that prints minimum cost required
def minimumCost(arr, cost, N):
  
    # Dp-table
    dp = [[0 for i in range(3)] for i in range(N)]
  
    # Base case
    # Not increasing the first element
    dp[0][0] = 0
  
    # Increasing the first element by 1
    dp[0][1] = cost[0]
  
    # Increasing the first element by 2
    dp[0][2] = cost[0] * 2
  
    for i in range(1, N):
        for j in range(3):
  
            minimum = 1e6
  
            # Condition if current element
            # is not equal to previous
            # non-increased element
            if (j + arr[i] != arr[i - 1]):
                minimum = min(minimum, dp[i - 1][0])
  
            # Condition if current element
            # is not equal to previous element
            # after being increased by 1
            if (j + arr[i] != arr[i - 1] + 1):
                minimum = min(minimum, dp[i - 1][1])
  
            # Condition if current element
            # is not equal to previous element
            # after being increased by 2
            if (j + arr[i] != arr[i - 1] + 2):
                minimum = min(minimum, dp[i - 1][2])
  
            # Take the minimum from all cases
            dp[i][j] = j * cost[i] + minimum
              
    ans = 1e6
  
    # Finding the minimum cost
    for i in range(3):
        ans = min(ans, dp[N - 1][i])
  
    # Printing the minimum cost
    # required to make all adjacent
    # elements disinct
    print(ans)
  
# Driver Code
if __name__ == '__main__':
      
    arr = [ 1, 1, 2, 2, 3, 4 ]
    cost = [ 3, 2, 5, 4, 2, 1 ]
    N = len(arr)
  
    minimumCost(arr, cost, N)
  
# This code is contributed by mohit kumar 29

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find the minimum 
// cost required to make all 
// adjacent elements disinct
using System;
  
class GFG{
  
// Function that prints minimum cost required
static void minimumCost(int []arr, int []cost,
                        int N)
{
  
    // Dp-table
    int [,]dp = new int[N, 3];
  
    // Base case
    // Not increasing the first element
    dp[0, 0] = 0;
  
    // Increasing the first element by 1
    dp[0, 1] = cost[0];
  
    // Increasing the first element by 2
    dp[0, 2] = cost[0] * 2;
  
    for(int i = 1; i < N; i++)
    {
       for(int j = 0; j < 3; j++)
       {
          int minimum = (int) 1e6;
            
          // Condition if current element
          // is not equal to previous
          // non-increased element
          if (j + arr[i] != arr[i - 1])
              minimum = Math.Min(minimum, 
                                 dp[i - 1, 0]);
            
          // Condition if current element
          // is not equal to previous element
          // after being increased by 1
          if (j + arr[i] != arr[i - 1] + 1)
              minimum = Math.Min(minimum, 
                                 dp[i - 1, 1]);
            
          // Condition if current element
          // is not equal to previous element
          // after being increased by 2
          if (j + arr[i] != arr[i - 1] + 2)
              minimum = Math.Min(minimum, 
                                 dp[i - 1, 2]);
            
          // Take the minimum from all cases
          dp[i, j] = j * cost[i] + minimum;
       }
    }
    int ans = (int) 1e6;
  
    // Finding the minimum cost
    for(int i = 0; i < 3; i++)
       ans = Math.Min(ans, dp[N - 1, i]);
         
    // Printing the minimum cost
    // required to make all adjacent
    // elements disinct
    Console.Write(ans + "\n");
}
  
// Driver Code
public static void Main(String[] args)
{
    int []arr = { 1, 1, 2, 2, 3, 4 };
    int []cost = { 3, 2, 5, 4, 2, 1 };
    int N = arr.Length;
  
    minimumCost(arr, cost, N);
}
}
  
// This code is contributed by 29AjayKumar

chevron_right


Output:

7

Time Complexity: O(N)
Auxillary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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 Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.