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

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:

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[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;` `}`

## 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[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.. `

## 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[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`

## 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[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.. `

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

Efficient approach : Using DP Tabulation method ( Iterative approach )

The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.

Steps to solve this problem :

• Create a DP to store the solution of the subproblems.
• Initialize the DP  with base cases
• Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP.
• Return the final solution minimum of min(dp[0][0], min(dp[0][1], dp[0][2])).

Implementation :

## C++

 `#include ` `using` `namespace` `std;`   `const` `int` `SIZE = 3;`   `// Function to return the minimized sum` `int` `minSum(``int` `A[], ``int` `B[], ``int` `C[]) {` `    ``int` `dp[SIZE][3];`   `    ``// Base case` `    ``dp[SIZE-1][0] = A[SIZE-1];` `    ``dp[SIZE-1][1] = B[SIZE-1];` `    ``dp[SIZE-1][2] = C[SIZE-1];`   `    ``// Tabulate the solution from bottom up` `    ``for``(``int` `i = SIZE-2; i >= 0; i--) {` `      `  `          ``// iterate over subproblems to get the current` `          ``// value from previous computaions` `        ``dp[i][0] = A[i] + min(dp[i+1][1], dp[i+1][2]);` `        ``dp[i][1] = B[i] + min(dp[i+1][0], dp[i+1][2]);` `        ``dp[i][2] = C[i] + min(dp[i+1][0], dp[i+1][1]);` `    ``}`   `    ``// Return the minimized sum` `    ``return` `min(dp[0][0], min(dp[0][1], dp[0][2]));` `}`   `// Driver code` `int` `main() {` `    ``int` `A[] = { 1, 50, 1 };` `    ``int` `B[] = { 50, 50, 50 };` `    ``int` `C[] = { 50, 50, 50 };` `    `  `      ``// function call` `    ``cout << minSum(A, B, C) << endl;` `    ``return` `0;` `}`

## Java

 `// Java program to return the minimized sum` `public` `class` `Main {` `    ``public` `static` `void` `main(String[] args) {` `        ``int` `SIZE = ``3``;` `        ``int``[] A = { ``1``, ``50``, ``1` `};` `        ``int``[] B = { ``50``, ``50``, ``50` `};` `        ``int``[] C = { ``50``, ``50``, ``50` `};`   `        ``int``[][] dp = ``new` `int``[SIZE][``3``];`   `        ``// Base case` `        ``dp[SIZE - ``1``][``0``] = A[SIZE - ``1``];` `        ``dp[SIZE - ``1``][``1``] = B[SIZE - ``1``];` `        ``dp[SIZE - ``1``][``2``] = C[SIZE - ``1``];`   `        ``// Tabulate the solution from bottom up` `        ``for` `(``int` `i = SIZE - ``2``; i >= ``0``; i--) {`   `            ``// Iterate over subproblems to get the current` `            ``// value from previous computations` `            ``dp[i][``0``] = A[i] + Math.min(dp[i + ``1``][``1``], dp[i + ``1``][``2``]);` `            ``dp[i][``1``] = B[i] + Math.min(dp[i + ``1``][``0``], dp[i + ``1``][``2``]);` `            ``dp[i][``2``] = C[i] + Math.min(dp[i + ``1``][``0``], dp[i + ``1``][``1``]);` `        ``}`   `        ``// Return the minimized sum` `        ``int` `result = Math.min(dp[``0``][``0``], Math.min(dp[``0``][``1``], dp[``0``][``2``]));` `        ``System.out.println(result);` `    ``}` `}`

## Python3

 `import` `sys`   `SIZE ``=` `3`   `# Function to return the minimized sum`     `def` `minSum(A, B, C):` `    ``dp ``=` `[[``0` `for` `j ``in` `range``(``3``)] ``for` `i ``in` `range``(SIZE)]`   `    ``# Base case` `    ``dp[SIZE``-``1``][``0``] ``=` `A[SIZE``-``1``]` `    ``dp[SIZE``-``1``][``1``] ``=` `B[SIZE``-``1``]` `    ``dp[SIZE``-``1``][``2``] ``=` `C[SIZE``-``1``]`   `    ``# Tabulate the solution from bottom up` `    ``for` `i ``in` `range``(SIZE``-``2``, ``-``1``, ``-``1``):` `        ``# iterate over subproblems to get the current` `        ``# value from previous computaions` `        ``dp[i][``0``] ``=` `A[i] ``+` `min``(dp[i``+``1``][``1``], dp[i``+``1``][``2``])` `        ``dp[i][``1``] ``=` `B[i] ``+` `min``(dp[i``+``1``][``0``], dp[i``+``1``][``2``])` `        ``dp[i][``2``] ``=` `C[i] ``+` `min``(dp[i``+``1``][``0``], dp[i``+``1``][``1``])`   `    ``# Return the minimized sum` `    ``return` `min``(dp[``0``][``0``], ``min``(dp[``0``][``1``], dp[``0``][``2``]))`     `# Driver code` `if` `__name__ ``=``=` `'__main__'``:` `    ``A ``=` `[``1``, ``50``, ``1``]` `    ``B ``=` `[``50``, ``50``, ``50``]` `    ``C ``=` `[``50``, ``50``, ``50``]`   `    ``# function call` `    ``print``(minSum(A, B, C))`

## C#

 `using` `System;`   `class` `Program` `{` `    ``const` `int` `SIZE = 3;`   `    ``// Function to return the minimized sum` `    ``static` `int` `MinSum(``int``[] A, ``int``[] B, ``int``[] C)` `    ``{` `        ``int``[,] dp = ``new` `int``[SIZE, 3];`   `        ``// Base case` `        ``dp[SIZE - 1, 0] = A[SIZE - 1];` `        ``dp[SIZE - 1, 1] = B[SIZE - 1];` `        ``dp[SIZE - 1, 2] = C[SIZE - 1];`   `        ``// Tabulate the solution from bottom up` `        ``for` `(``int` `i = SIZE - 2; i >= 0; i--)` `        ``{` `            ``// Iterate over subproblems to get the current` `            ``// value from previous computations` `            ``dp[i, 0] = A[i] + Math.Min(dp[i + 1, 1], dp[i + 1, 2]);` `            ``dp[i, 1] = B[i] + Math.Min(dp[i + 1, 0], dp[i + 1, 2]);` `            ``dp[i, 2] = C[i] + Math.Min(dp[i + 1, 0], dp[i + 1, 1]);` `        ``}`   `        ``// Return the minimized sum` `        ``return` `Math.Min(dp[0, 0], Math.Min(dp[0, 1], dp[0, 2]));` `    ``}`   `    ``// Driver Code` `    ``static` `void` `Main()` `    ``{` `        ``int``[] A = { 1, 50, 1 };` `        ``int``[] B = { 50, 50, 50 };` `        ``int``[] C = { 50, 50, 50 };`   `        ``// Function call` `        ``Console.WriteLine(MinSum(A, B, C));` `    ``}` `}`

## Javascript

 `const SIZE = 3;`   `// Function to return the minimized sum` `function` `minSum(A, B, C) {` `    ``const dp = ``new` `Array(SIZE).fill().map(() => ``new` `Array(3));`   `    ``// Base case` `    ``dp[SIZE - 1][0] = A[SIZE - 1];` `    ``dp[SIZE - 1][1] = B[SIZE - 1];` `    ``dp[SIZE - 1][2] = C[SIZE - 1];`   `    ``// Tabulate the solution from bottom up` `    ``for` `(let i = SIZE - 2; i >= 0; i--) {` `        ``// Iterate over subproblems to get the current` `        ``// value from previous computations` `        ``dp[i][0] = A[i] + Math.min(dp[i + 1][1], dp[i + 1][2]);` `        ``dp[i][1] = B[i] + Math.min(dp[i + 1][0], dp[i + 1][2]);` `        ``dp[i][2] = C[i] + Math.min(dp[i + 1][0], dp[i + 1][1]);` `    ``}`   `    ``// Return the minimized sum` `    ``return` `Math.min(dp[0][0], Math.min(dp[0][1], dp[0][2]));` `}`   `// Driver code` `const A = [1, 50, 1];` `const B = [50, 50, 50];` `const C = [50, 50, 50];`   `// Function call` `console.log(minSum(A, B, C));`

Output

```52

```

Time Complexity: O(n), where n is the size of the arrays A, B, and C.
Auxiliary Space: O(n), as the dp array has n rows and 3 columns

Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!