Skip to content
Related Articles

Related Articles

Minimize the sum after choosing elements from the given three arrays
  • Difficulty Level : Medium
  • Last Updated : 14 Oct, 2019

Given three arrays A[], B[] and C[] of same size N. The task is to minimize the sum after choosing N elements from these array such that at every index i an element from any one of the array A[i], B[i] or C[i] can be chosen and no two consecutive elements can be chosen from the same array.

Examples:

Input: A[] = {1, 100, 1}, B[] = {100, 100, 100}, C[] = {100, 100, 100}
Output: 102
A[0] + B[1] + A[2] = 1 + 100 + 100 = 201
A[0] + B[1] + C[2] = 1 + 100 + 100 = 201
A[0] + C[1] + B[2] = 1 + 100 + 100 = 201
A[0] + C[1] + A[2] = 1 + 100 + 1 = 102
B[0] + A[1] + B[2] = 100 + 100 + 100 = 300
B[0] + A[1] + C[2] = 100 + 100 + 100 = 300
B[0] + C[1] + A[2] = 100 + 100 + 1 = 201
B[0] + C[1] + B[2] = 100 + 100 + 100 = 300
C[0] + A[1] + B[2] = 100 + 100 + 100 = 300
C[0] + A[1] + C[2] = 100 + 100 + 100 = 300
C[0] + B[1] + A[2] = 100 + 100 + 1 = 201
C[0] + B[1] + C[2] = 100 + 100 + 100 = 300

Input: A[] = {1, 1, 1}, B[] = {1, 1, 1}, C[] = {1, 1, 1}
Output: 3

Approach: The problem is a simple variation of finding minimum cost. The extra constraint are that if we take an element from a particular array then we cannot take the next element from the same array. This could easily be solved using recursion but it would give time complexity as O(3^n) because for every element we have three arrays as choices.



To improve the time complexity we can easily store the pre-calculated values in a dp array.

Since there are three arrays to choose from at every index, three cases arise in this scenario:

  • Case 1: If array A[] is selected from the ith element then we either choose the array B[] or the array C[] for the (i + 1)th element.
  • Case 2: If array B[] is selected from the ith element then we either choose the array A[] or the array C[] for the (i + 1)th element.
  • Case 3: If array C[] is selected from the ith element then we either choose the array A[] or the array B[] for the (i + 1)th element.

The above states can be solved using recursion and intermediate results can be stored in the dp array.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the above approach
  
#include <bits/stdc++.h>
using namespace std;
#define SIZE 3
const int N = 3;
  
// Function to return the minimized sum
int minSum(int A[], int B[], int C[], int i,
        int n, int curr, int dp[SIZE][N])
{
  
    // If all the indices have been used
    if (n <= 0)
        return 0;
  
    // If this value is pre-calculated
    // then return its value from dp array
    // instead of re-computing it
    if (dp[n][curr] != -1)
        return dp[n][curr];
  
    // Here curr is the array chosen
    // for the (i - 1)th element
    // 0 for A[], 1 for B[] and 2 for C[]
  
    // If A[i - 1] was chosen previously then
    // only B[i] or C[i] can chosen now
    // choose the one which leads
    // to the minimum sum
    if (curr == 0) {
        return dp[n][curr] 
                = min(B[i] + minSum(A, B, C, i + 1, n - 1, 1, dp),
                      C[i] + minSum(A, B, C, i + 1, n - 1, 2, dp));
    }
  
    // If B[i - 1] was chosen previously then
    // only A[i] or C[i] can chosen now
    // choose the one which leads
    // to the minimum sum
    if (curr == 1)
        return dp[n][curr] 
                = min(A[i] + minSum(A, B, C, i + 1, n - 1, 0, dp),
                      C[i] + minSum(A, B, C, i + 1, n - 1, 2, dp));
  
    // If C[i - 1] was chosen previously then
    // only A[i] or B[i] can chosen now
    // choose the one which leads
    // to the minimum sum
    return dp[n][curr] 
                = min(A[i] + minSum(A, B, C, i + 1, n - 1, 0, dp),
                      B[i] + minSum(A, B, C, i + 1, n - 1, 1, dp));
}
  
// Driver code
int main()
{
    int A[] = { 1, 50, 1 };
    int B[] = { 50, 50, 50 };
    int C[] = { 50, 50, 50 };
  
    // Initialize the dp[][] array
    int dp[SIZE][N];
    for (int i = 0; i < SIZE; i++)
        for (int j = 0; j < N; j++)
            dp[i][j] = -1;
  
    // min(start with A[0], start with B[0], start with C[0])
    cout << min(A[0] + minSum(A, B, C, 1, SIZE - 1, 0, dp),
                min(B[0] + minSum(A, B, C, 1, SIZE - 1, 1, dp),
                    C[0] + minSum(A, B, C, 1, SIZE - 1, 2, dp)));
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the above approach
import java.io.*;
  
class GFG 
{
  
static int SIZE = 3;
static int N = 3;
  
// Function to return the minimized sum
static int minSum(int A[], int B[], int C[], int i,
                    int n, int curr, int [][]dp)
{
  
    // If all the indices have been used
    if (n <= 0)
        return 0;
  
    // If this value is pre-calculated
    // then return its value from dp array
    // instead of re-computing it
    if (dp[n][curr] != -1)
        return dp[n][curr];
  
    // Here curr is the array chosen
    // for the (i - 1)th element
    // 0 for A[], 1 for B[] and 2 for C[]
  
    // If A[i - 1] was chosen previously then
    // only B[i] or C[i] can chosen now
    // choose the one which leads
    // to the minimum sum
    if (curr == 0
    {
        return dp[n][curr] 
                = Math.min(B[i] + minSum(A, B, C, i + 1, n - 1, 1, dp),
                    C[i] + minSum(A, B, C, i + 1, n - 1, 2, dp));
    }
  
    // If B[i - 1] was chosen previously then
    // only A[i] or C[i] can chosen now
    // choose the one which leads
    // to the minimum sum
    if (curr == 1)
        return dp[n][curr] 
                = Math.min(A[i] + minSum(A, B, C, i + 1, n - 1, 0, dp),
                    C[i] + minSum(A, B, C, i + 1, n - 1, 2, dp));
  
    // If C[i - 1] was chosen previously then
    // only A[i] or B[i] can chosen now
    // choose the one which leads
    // to the minimum sum
    return dp[n][curr] 
                = Math.min(A[i] + minSum(A, B, C, i + 1, n - 1, 0, dp),
                    B[i] + minSum(A, B, C, i + 1, n - 1, 1, dp));
}
  
// Driver code
public static void main (String[] args) 
{
    int A[] = { 1, 50, 1 };
    int B[] = { 50, 50, 50 };
    int C[] = { 50, 50, 50 };
      
    // Initialize the dp[][] array
    int dp[][] = new int[SIZE][N];
    for (int i = 0; i < SIZE; i++)
        for (int j = 0; j < N; j++)
            dp[i][j] = -1;
      
    // min(start with A[0], start with B[0], start with C[0])
    System.out.println(Math.min(A[0] + minSum(A, B, C, 1, SIZE - 1, 0, dp),
                Math.min(B[0] + minSum(A, B, C, 1, SIZE - 1, 1, dp),
                    C[0] + minSum(A, B, C, 1, SIZE - 1, 2, dp))));
}
}
  
// This code is contributed by anuj_67.. 

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the above approach 
  
import numpy as np
  
SIZE = 3
N = 3
  
# Function to return the minimized sum 
def minSum(A, B, C, i, n, curr, dp) : 
  
    # If all the indices have been used 
    if (n <= 0) :
        return 0
  
    # If this value is pre-calculated 
    # then return its value from dp array 
    # instead of re-computing it 
    if (dp[n][curr] != -1) :
        return dp[n][curr]; 
  
    # Here curr is the array chosen 
    # for the (i - 1)th element 
    # 0 for A[], 1 for B[] and 2 for C[] 
  
    # If A[i - 1] was chosen previously then 
    # only B[i] or C[i] can chosen now 
    # choose the one which leads 
    # to the minimum sum 
    if (curr == 0) : 
        dp[n][curr] = min( B[i] + minSum(A, B, C, i + 1, n - 1, 1, dp), 
        C[i] + minSum(A, B, C, i + 1, n - 1, 2, dp)); 
        return dp[n][curr] 
      
  
    # If B[i - 1] was chosen previously then 
    # only A[i] or C[i] can chosen now 
    # choose the one which leads 
    # to the minimum sum 
    if (curr == 1) :
        dp[n][curr] = min(A[i] + minSum(A, B, C, i + 1, n - 1, 0, dp), 
        C[i] + minSum(A, B, C, i + 1, n - 1, 2, dp)); 
        return dp[n][curr]
  
    # If C[i - 1] was chosen previously then 
    # only A[i] or B[i] can chosen now 
    # choose the one which leads 
    # to the minimum sum 
    dp[n][curr] = min(A[i] + minSum(A, B, C, i + 1, n - 1, 0, dp), 
    B[i] + minSum(A, B, C, i + 1, n - 1, 1, dp)); 
      
    return dp[n][curr]
  
  
# Driver code 
if __name__ == "__main__"
  
    A = [ 1, 50, 1 ]; 
    B = [ 50, 50, 50 ]; 
    C = [ 50, 50, 50 ]; 
  
    # Initialize the dp[][] array 
    dp = np.zeros((SIZE,N)); 
      
    for i in range(SIZE) :
        for j in range(N) : 
            dp[i][j] = -1
  
    # min(start with A[0], start with B[0], start with C[0]) 
    print(min(A[0] + minSum(A, B, C, 1, SIZE - 1, 0, dp), 
                min(B[0] + minSum(A, B, C, 1, SIZE - 1, 1, dp), 
                C[0] + minSum(A, B, C, 1, SIZE - 1, 2, dp)))); 
  
# This code is contributed by AnkitRai01

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the above approach
using System;
  
class GFG 
{
  
static int SIZE = 3;
static int N = 3;
  
// Function to return the minimized sum
static int minSum(int []A, int []B, int []C, int i,
                    int n, int curr, int [,]dp)
{
  
    // If all the indices have been used
    if (n <= 0)
        return 0;
  
    // If this value is pre-calculated
    // then return its value from dp array
    // instead of re-computing it
    if (dp[n,curr] != -1)
        return dp[n,curr];
  
    // Here curr is the array chosen
    // for the (i - 1)th element
    // 0 for A[], 1 for B[] and 2 for C[]
  
    // If A[i - 1] was chosen previously then
    // only B[i] or C[i] can chosen now
    // choose the one which leads
    // to the minimum sum
    if (curr == 0) 
    {
        return dp[n,curr] 
                = Math.Min(B[i] + minSum(A, B, C, i + 1, n - 1, 1, dp),
                    C[i] + minSum(A, B, C, i + 1, n - 1, 2, dp));
    }
  
    // If B[i - 1] was chosen previously then
    // only A[i] or C[i] can chosen now
    // choose the one which leads
    // to the minimum sum
    if (curr == 1)
        return dp[n,curr] 
                = Math.Min(A[i] + minSum(A, B, C, i + 1, n - 1, 0, dp),
                    C[i] + minSum(A, B, C, i + 1, n - 1, 2, dp));
  
    // If C[i - 1] was chosen previously then
    // only A[i] or B[i] can chosen now
    // choose the one which leads
    // to the minimum sum
    return dp[n,curr] 
                = Math.Min(A[i] + minSum(A, B, C, i + 1, n - 1, 0, dp),
                    B[i] + minSum(A, B, C, i + 1, n - 1, 1, dp));
}
  
// Driver code
public static void Main () 
{
    int []A = { 1, 50, 1 };
    int []B = { 50, 50, 50 };
    int []C = { 50, 50, 50 };
      
    // Initialize the dp[][] array
    int [,]dp = new int[SIZE,N];
    for (int i = 0; i < SIZE; i++)
        for (int j = 0; j < N; j++)
            dp[i,j] = -1;
      
    // min(start with A[0], start with B[0], start with C[0])
    Console.WriteLine(Math.Min(A[0] + minSum(A, B, C, 1, SIZE - 1, 0, dp),
                Math.Min(B[0] + minSum(A, B, C, 1, SIZE - 1, 1, dp),
                    C[0] + minSum(A, B, C, 1, SIZE - 1, 2, dp))));
}
}
  
// This code is contributed by anuj_67.. 

chevron_right


Output:

52

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
Recommended Articles
Page :