# Minimize the sum after choosing elements from the given three arrays

• Difficulty Level : Medium
• Last Updated : 24 Apr, 2022

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 + B + A = 1 + 100 + 100 = 201
A + B + C = 1 + 100 + 100 = 201
A + C + B = 1 + 100 + 100 = 201
A + C + A = 1 + 100 + 1 = 102
B + A + B = 100 + 100 + 100 = 300
B + A + C = 100 + 100 + 100 = 300
B + C + A = 100 + 100 + 1 = 201
B + C + B = 100 + 100 + 100 = 300
C + A + B = 100 + 100 + 100 = 300
C + A + C = 100 + 100 + 100 = 300
C + B + A = 100 + 100 + 1 = 201
C + B + C = 100 + 100 + 100 = 300
Input: A[] = {1, 1, 1}, B[] = {1, 1, 1}, C[] = {1, 1, 1}
Output:

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++

 `// C++ implementation of the above approach` `#include ``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, start with B, start with C)``    ``cout << min(A + minSum(A, B, C, 1, SIZE - 1, 0, dp),``                ``min(B + minSum(A, B, C, 1, SIZE - 1, 1, dp),``                    ``C + minSum(A, B, C, 1, SIZE - 1, 2, dp)));` `    ``return` `0;``}`

## Java

 `// 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, start with B, start with C)``    ``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..`

## Python3

 `# 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, start with B, start with C)``    ``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`

## C#

 `// 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, start with B, start with C)``    ``Console.WriteLine(Math.Min(A + minSum(A, B, C, 1, SIZE - 1, 0, dp),``                ``Math.Min(B + minSum(A, B, C, 1, SIZE - 1, 1, dp),``                    ``C + minSum(A, B, C, 1, SIZE - 1, 2, dp))));``}``}` `// This code is contributed by anuj_67..`

## Javascript

 ``
Output:
`52`

Time Complexity: O(SIZE*N), where dp operations taking SIZE*N time
Auxiliary Space: O(SIZE*N), where dp array is made of two states SIZE*N

My Personal Notes arrow_drop_up