Given three arrays A, B, and C each having N elements, the task is to find the maximum sum that can be obtained along any valid path with at most K jumps.
A path is valid if it follows the following properties:
- It starts from the 0th index of an array.
- It ends at (N-1)th index of an array.
- For any element in the path at index i, the next element should be on the index i+1 of either current or adjacent array only.
- If the path involves selecting the next (i + 1)th element from the adjacent array, instead of the current one, then it is said to be 1 jump
Examples:
Input: A[] = {4, 5, 1, 2, 10}, B[] = {9, 7, 3, 20, 16}, C[] = {6, 12, 13, 9, 8}, K = 2
Output: 70
Explanation:
Starting from array B and selecting the elements as follows:
Select B[0]: 9 => sum = 9
Jump to C[1]: 12 => sum = 21
Select C[2]: 13 => sum = 34
Jump to B[3]: 20 => sum = 54
Select B[4]: 16 => sum = 70
Therefore maximum sum with at most 2 jumps = 70
Input: A[] = {10, 4, 1, 8}, B[] = {9, 0, 2, 5}, C[] = {6, 2, 7, 3}, K = 2
Output: 24
Intuitive Greedy Approach (Not Correct): One possible idea to solve the problem could be to pick the maximum element at the current index and move to the next index having maximum value either from the current array or the adjacent array if jumps are left.
For example:
Given,
A[] = {4, 5, 1, 2, 10},
B[] = {9, 7, 3, 20, 16},
C[] = {6, 12, 13, 9, 8},
K = 2
Finding the solution using the Greedy approach:
Current maximum: 9, K = 2, sum = 9
Next maximum: 12, K = 1, sum = 12
Next maximum: 13, K = 1, sum = 25
Next maximum: 20, K = 0, sum = 45
Adding rest of elements: 16, K = 0, sum = 61
Clearly, this is not the maximum sum.
Hence, this approach is incorrect.
Dynamic Programming Approach: The DP can be used in two steps – Recursion and Memoization.
- Recursion: The problem could be broken down using the following recursive relation:
- On Array A, index i with K jumps
pathSum(A, i, k) = A[i] + max(pathSum(A, i+1, k), pathSum(B, i+1, k-1));
pathSum(B, i, k) = B[i] + max(pathSum(B, i+1, k), max(pathSum(A, i+1, k-1), pathSum(C, i+1, k-1));
pathSum(C, i, k) = C[i] + max(pathSum(C, i+1, k), pathSum(B, i+1, k-1));
- Therefore, the maximum sum can be found as:
maxSum = max(pathSum(A, i, k), max(pathSum(B, i, k), pathSum(C, i, k)));
- Memoization: The complexity of the above recursion solution can be reduced with the help of memoization.
- Store the results after calculating in a 3-dimensional array (dp) of size [3][N][K].
- The value of any element of dp array stores the maximum sum on ith index with x jumps left in an array
Below is the implementation of the approach:
C++
#include <iostream>
using namespace std;
#define M 3
#define N 5
#define K 2
int dp[M][N][K];
void initializeDp()
{
for ( int i = 0; i < M; i++)
for ( int j = 0; j < N; j++)
for ( int k = 0; k < K; k++)
dp[i][j][k] = -1;
}
int pathSum( int * a, int * b, int * c,
int i, int n,
int k, int on)
{
if (i == n)
return 0;
if (dp[on][i][k] != -1)
return dp[on][i][k];
int current, sum;
switch (on) {
case 0:
current = a[i];
break ;
case 1:
current = b[i];
break ;
case 2:
current = c[i];
break ;
}
if (k == 0) {
return dp[on][i][k]
= current
+ pathSum(a, b, c, i + 1,
n, k, on);
}
switch (on) {
case 0:
sum = current
+ max(pathSum(a, b, c, i + 1,
n, k - 1, 1),
pathSum(a, b, c, i + 1,
n, k, 0));
break ;
case 1:
sum = current
+ max(pathSum(a, b, c, i + 1,
n, k - 1, 0),
max(pathSum(a, b, c, i + 1,
n, k, 1),
pathSum(a, b, c, i + 1,
n, k - 1, 2)));
break ;
case 2:
sum = current
+ max(pathSum(a, b, c, i + 1,
n, k - 1, 1),
pathSum(a, b, c, i + 1,
n, k, 2));
break ;
}
return dp[on][i][k] = sum;
}
void findMaxSum( int * a, int * b,
int * c, int n, int k)
{
int sum = 0;
initializeDp();
for ( int i = 0; i < 3; i++) {
sum = max(sum,
pathSum(a, b, c, 0,
n, k, i));
}
cout << sum;
}
int main()
{
int n = 5, k = 1;
int A[n] = { 4, 5, 1, 2, 10 };
int B[n] = { 9, 7, 3, 20, 16 };
int C[n] = { 6, 12, 13, 9, 8 };
findMaxSum(A, B, C, n, k);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int M = 3 ;
static int N = 5 ;
static int K = 2 ;
static int dp[][][] = new int [M][N][K];
static void initializeDp()
{
for ( int i = 0 ; i < M; i++)
for ( int j = 0 ; j < N; j++)
for ( int k = 0 ; k < K; k++)
dp[i][j][k] = - 1 ;
}
static int pathSum( int a[], int b[], int c[],
int i, int n,
int k, int on)
{
if (i == n)
return 0 ;
if (dp[on][i][k] != - 1 )
return dp[on][i][k];
int current = 0 , sum = 0 ;
switch (on) {
case 0 :
current = a[i];
break ;
case 1 :
current = b[i];
break ;
case 2 :
current = c[i];
break ;
}
if (k == 0 ) {
return dp[on][i][k]
= current
+ pathSum(a, b, c, i + 1 ,
n, k, on);
}
switch (on) {
case 0 :
sum = current
+ Math.max(pathSum(a, b, c, i + 1 ,
n, k - 1 , 1 ),
pathSum(a, b, c, i + 1 ,
n, k, 0 ));
break ;
case 1 :
sum = current
+ Math.max(pathSum(a, b, c, i + 1 ,
n, k - 1 , 0 ),
Math.max(pathSum(a, b, c, i + 1 ,
n, k, 1 ),
pathSum(a, b, c, i + 1 ,
n, k - 1 , 2 )));
break ;
case 2 :
sum = current
+ Math.max(pathSum(a, b, c, i + 1 ,
n, k - 1 , 1 ),
pathSum(a, b, c, i + 1 ,
n, k, 2 ));
break ;
}
return dp[on][i][k] = sum;
}
static void findMaxSum( int a[], int b[],
int c[], int n, int k)
{
int sum = 0 ;
initializeDp();
for ( int i = 0 ; i < 3 ; i++) {
sum = Math.max(sum,
pathSum(a, b, c, 0 ,
n, k, i));
}
System.out.print(sum);
}
public static void main(String []args)
{
int n = 5 , k = 1 ;
int A[] = { 4 , 5 , 1 , 2 , 10 };
int B[] = { 9 , 7 , 3 , 20 , 16 };
int C[] = { 6 , 12 , 13 , 9 , 8 };
findMaxSum(A, B, C, n, k);
}
}
|
Python
M = 3
N = 5
K = 2
dp = [[[ - 1 for i in range (K)]
for i in range (N)]
for i in range (M)]
def initializeDp():
for i in range (M):
for j in range (N):
for k in range (K):
dp[i][j][k] = - 1
def pathSum(a, b, c, i, n, k, on):
if (i = = n):
return 0
if (dp[on][i][k] ! = - 1 ):
return dp[on][i][k]
current, sum = 0 , 0
if on = = 0 :
current = a[i]
if on = = 1 :
current = b[i]
if on = = 2 :
current = c[i]
if (k = = 0 ):
dp[on][i][k] = current +
pathSum(a, b, c,
i + 1 , n, k, on)
return dp[on][i][k]
if on = = 0 :
sum = current + max (pathSum(a, b, c, i + 1 ,
n, k - 1 , 1 ),
pathSum(a, b, c,
i + 1 , n, k, 0 ))
if on = = 1 :
sum = current + max (pathSum(a, b, c, i + 1 ,
n, k - 1 , 0 ),
max (pathSum(a, b, c, i + 1 ,
n, k, 1 ),
pathSum(a, b, c, i + 1 ,
n, k - 1 , 2 )))
if on = = 2 :
sum = current + max (pathSum(a, b, c, i + 1 ,
n, k - 1 , 1 ),
pathSum(a, b, c, i + 1 ,
n, k, 2 ))
dp[on][i][k] = sum
return sum
def findMaxSum(a, b, c, n, k):
sum = 0
initializeDp()
for i in range ( 3 ):
sum = max ( sum , pathSum(a, b, c, 0 , n, k, i))
print ( sum )
if __name__ = = '__main__' :
n = 5
k = 1
A = [ 4 , 5 , 1 , 2 , 10 ]
B = [ 9 , 7 , 3 , 20 , 16 ]
C = [ 6 , 12 , 13 , 9 , 8 ]
findMaxSum(A, B, C, n, k)
|
C#
using System;
class GFG{
static int M = 3;
static int N = 5;
static int K = 2;
static int [,,]dp = new int [M, N, K];
static void initializeDp()
{
for ( int i = 0; i < M; i++)
for ( int j = 0; j < N; j++)
for ( int k = 0; k < K; k++)
dp[i, j, k] = -1;
}
static int pathSum( int []a, int []b, int []c,
int i, int n,
int k, int on )
{
if (i == n)
return 0;
if (dp[ on , i, k] != -1)
return dp[ on , i, k];
int current = 0, sum = 0;
switch ( on )
{
case 0:
current = a[i];
break ;
case 1:
current = b[i];
break ;
case 2:
current = c[i];
break ;
}
if (k == 0)
{
return dp[ on , i, k] = current +
pathSum(a, b, c, i + 1,
n, k, on );
}
switch ( on )
{
case 0:
sum = current + Math.Max(pathSum(a, b, c, i + 1,
n, k - 1, 1),
pathSum(a, b, c, i + 1,
n, k, 0));
break ;
case 1:
sum = current + Math.Max(pathSum(a, b, c, i + 1,
n, k - 1, 0),
Math.Max(pathSum(a, b, c, i + 1,
n, k, 1),
pathSum(a, b, c, i + 1,
n, k - 1, 2)));
break ;
case 2:
sum = current + Math.Max(pathSum(a, b, c, i + 1,
n, k - 1, 1),
pathSum(a, b, c, i + 1,
n, k, 2));
break ;
}
return dp[ on , i, k] = sum;
}
static void findMaxSum( int []a, int []b,
int []c, int n, int k)
{
int sum = 0;
initializeDp();
for ( int i = 0; i < 3; i++)
{
sum = Math.Max(sum, pathSum(a, b, c, 0,
n, k, i));
}
Console.Write(sum);
}
public static void Main(String []args)
{
int n = 5, k = 1;
int []A = { 4, 5, 1, 2, 10 };
int []B = { 9, 7, 3, 20, 16 };
int []C = { 6, 12, 13, 9, 8 };
findMaxSum(A, B, C, n, k);
}
}
|
Javascript
<script>
let M = 3;
let N = 5;
let K = 2;
let dp= new Array(M);
function initializeDp()
{
for (let i = 0; i < M; i++)
{
dp[i]= new Array(N);
for (let j = 0; j < N; j++)
{
dp[i][j]= new Array(K);
for (let k = 0; k < K; k++)
dp[i][j][k] = -1;
}
}
}
function pathSum(a,b,c,i,n,k,on)
{
if (i == n)
return 0;
if (dp[on][i][k] != -1)
return dp[on][i][k];
let current = 0, sum = 0;
switch (on) {
case 0:
current = a[i];
break ;
case 1:
current = b[i];
break ;
case 2:
current = c[i];
break ;
}
if (k == 0) {
return dp[on][i][k]
= current
+ pathSum(a, b, c, i + 1,
n, k, on);
}
switch (on) {
case 0:
sum = current
+ Math.max(pathSum(a, b, c, i + 1,
n, k - 1, 1),
pathSum(a, b, c, i + 1,
n, k, 0));
break ;
case 1:
sum = current
+ Math.max(pathSum(a, b, c, i + 1,
n, k - 1, 0),
Math.max(pathSum(a, b, c, i + 1,
n, k, 1),
pathSum(a, b, c, i + 1,
n, k - 1, 2)));
break ;
case 2:
sum = current
+ Math.max(pathSum(a, b, c, i + 1,
n, k - 1, 1),
pathSum(a, b, c, i + 1,
n, k, 2));
break ;
}
return dp[on][i][k] = sum;
}
function findMaxSum(a,b,c,n,k)
{
let sum = 0;
initializeDp();
for (let i = 0; i < 3; i++) {
sum = Math.max(sum,
pathSum(a, b, c, 0,
n, k, i));
}
document.write(sum);
}
let n = 5, k = 1;
let A=[4, 5, 1, 2, 10];
let B=[9, 7, 3, 20, 16];
let C=[6, 12, 13, 9, 8 ];
findMaxSum(A, B, C, n, k);
</script>
|
Time Complexity: O(N * K)
Auxiliary Space: O(N * K)
Another approach : Dp tabulation (iterative)
In previous approach we solve the problem using recursion + memoization and use where we use DP to store the computation and also check whether we compute the particular problem previously or not but in this approach we solve the problem iteratively by using only DP and no recursion.
Implementation Steps:
- Create a 3d Dp to store computation previous of previous subproblems.
- Initialize DP with base cases.
- Here dp[i][j][x] stores the maximum sum using at most x jumps till index j of the i-th array.
- Initialize 3 nested loops to compute every subpreoblems.
- Noe initialize a variable nextMax with 0 and Calculate maximum sum possible after making a jump from the current array.
- At last initialize the variable maxSum the contains maximum sum is the maximum value in the dp table.
- Finally print maxSum.
Implementation:
C++
#include <iostream>
#include <algorithm>
using namespace std;
#define M 3
#define N 5
#define K 2
int dp[M][N][K];
void findMaxSum( int * a, int * b,
int * c, int n, int k)
{
for ( int i = 0; i < M; i++)
for ( int j = 0; j < N; j++)
for ( int x = 0; x <= k; x++)
dp[i][j][x] = 0;
for ( int x = 0; x <= k; x++) {
for ( int j = n - 1; j >= 0; j--) {
for ( int i = 0; i < M; i++) {
int current;
switch (i) {
case 0:
current = a[j];
break ;
case 1:
current = b[j];
break ;
case 2:
current = c[j];
break ;
}
if (j == n - 1) {
dp[i][j][x] = current;
}
else if (x == 0) {
dp[i][j][x] = current + dp[i][j + 1][x];
}
else {
int nextMax = 0;
for ( int next = 0; next < M; next++) {
if (next != i) {
nextMax = max(nextMax, dp[next][j + 1][x - 1]);
}
else {
nextMax = max(nextMax, dp[next][j + 1][x]);
}
}
dp[i][j][x] = current + nextMax;
}
}
}
}
int maxSum = 0;
for ( int i = 0; i < M; i++) {
maxSum = max(maxSum, dp[i][0][k]);
}
cout << maxSum << endl;
}
int main()
{
int n = 5, k = 1;
int A[n] = { 4, 5, 1, 2, 10 };
int B[n] = { 9, 7, 3, 20, 16 };
int C[n] = { 6, 12, 13, 9, 8 };
findMaxSum(A, B, C, n, k);
return 0;
}
|
Java
import java.util.*;
public class Main {
static final int M = 3 ;
static final int N = 5 ;
static final int K = 2 ;
static int [][][] dp = new int [M][N][K + 1 ];
static void findMaxSum( int [] a, int [] b, int [] c, int n, int k)
{
for ( int i = 0 ; i < M; i++) {
for ( int j = 0 ; j < N; j++) {
for ( int x = 0 ; x <= k; x++) {
dp[i][j][x] = 0 ;
}
}
}
for ( int x = 0 ; x <= k; x++) {
for ( int j = n - 1 ; j >= 0 ; j--) {
for ( int i = 0 ; i < M; i++) {
int current;
switch (i) {
case 0 :
current = a[j];
break ;
case 1 :
current = b[j];
break ;
case 2 :
current = c[j];
break ;
default :
current = 0 ;
break ;
}
if (j == n - 1 ) {
dp[i][j][x] = current;
} else if (x == 0 ) {
dp[i][j][x] = current + dp[i][j + 1 ][x];
} else {
int nextMax = 0 ;
for ( int next = 0 ; next < M; next++) {
if (next != i) {
nextMax = Math.max(nextMax, dp[next][j + 1 ][x - 1 ]);
} else {
nextMax = Math.max(nextMax, dp[next][j + 1 ][x]);
}
}
dp[i][j][x] = current + nextMax;
}
}
}
}
int maxSum = 0 ;
for ( int i = 0 ; i < M; i++) {
maxSum = Math.max(maxSum, dp[i][ 0 ][k]);
}
System.out.println(maxSum);
}
public static void main(String[] args) {
int n = 5 , k = 1 ;
int [] A = { 4 , 5 , 1 , 2 , 10 };
int [] B = { 9 , 7 , 3 , 20 , 16 };
int [] C = { 6 , 12 , 13 , 9 , 8 };
findMaxSum(A, B, C, n, k);
}
}
|
Python3
def findMaxSum(a, b, c, n, k):
dp = [[[ 0 for _ in range (k + 1 )] for _ in range (n)] for _ in range ( 3 )]
for x in range (k + 1 ):
for j in range (n - 1 , - 1 , - 1 ):
for i in range ( 3 ):
current = 0
if i = = 0 :
current = a[j]
elif i = = 1 :
current = b[j]
elif i = = 2 :
current = c[j]
if j = = n - 1 :
dp[i][j][x] = current
elif x = = 0 :
dp[i][j][x] = current + dp[i][j + 1 ][x]
else :
nextMax = 0
for nextArr in range ( 3 ):
if nextArr ! = i:
nextMax = max (nextMax, dp[nextArr][j + 1 ][x - 1 ])
else :
nextMax = max (nextMax, dp[nextArr][j + 1 ][x])
dp[i][j][x] = current + nextMax
maxSum = 0
for i in range ( 3 ):
maxSum = max (maxSum, dp[i][ 0 ][k])
print (maxSum)
if __name__ = = "__main__" :
n = 5
k = 1
A = [ 4 , 5 , 1 , 2 , 10 ]
B = [ 9 , 7 , 3 , 20 , 16 ]
C = [ 6 , 12 , 13 , 9 , 8 ]
findMaxSum(A, B, C, n, k)
|
C#
using System;
class Program
{
const int M = 3;
const int N = 5;
const int K = 2;
static int [,,] dp = new int [M, N, K + 1];
static void FindMaxSum( int [] a, int [] b, int [] c, int n, int k)
{
for ( int i = 0; i < M; i++)
{
for ( int j = 0; j < N; j++)
{
for ( int x = 0; x <= k; x++)
{
dp[i, j, x] = 0;
}
}
}
for ( int x = 0; x <= k; x++)
{
for ( int j = n - 1; j >= 0; j--)
{
for ( int i = 0; i < M; i++)
{
int current = 0;
switch (i)
{
case 0:
current = a[j];
break ;
case 1:
current = b[j];
break ;
case 2:
current = c[j];
break ;
}
if (j == n - 1)
{
dp[i, j, x] = current;
}
else if (x == 0)
{
dp[i, j, x] = current + dp[i, j + 1, x];
}
else
{
int nextMax = 0;
for ( int next = 0; next < M; next++)
{
if (next != i)
{
nextMax = Math.Max(nextMax, dp[next, j + 1, x - 1]);
}
else
{
nextMax = Math.Max(nextMax, dp[next, j + 1, x]);
}
}
dp[i, j, x] = current + nextMax;
}
}
}
}
int maxSum = 0;
for ( int i = 0; i < M; i++)
{
maxSum = Math.Max(maxSum, dp[i, 0, k]);
}
Console.WriteLine(maxSum);
}
static void Main()
{
int n = 5, k = 1;
int [] A = { 4, 5, 1, 2, 10 };
int [] B = { 9, 7, 3, 20, 16 };
int [] C = { 6, 12, 13, 9, 8 };
FindMaxSum(A, B, C, n, k);
}
}
|
Javascript
const M = 3;
const N = 5;
const K = 2;
const dp = new Array(M).fill(0).map(() => new Array(N).fill(0).map(() => new Array(K + 1).fill(0)));
function findMaxSum(a, b, c, n, k) {
for (let i = 0; i < M; i++) {
for (let j = 0; j < N; j++) {
for (let x = 0; x <= k; x++) {
dp[i][j][x] = 0;
}
}
}
for (let x = 0; x <= k; x++) {
for (let j = n - 1; j >= 0; j--) {
for (let i = 0; i < M; i++) {
let current;
switch (i) {
case 0:
current = a[j];
break ;
case 1:
current = b[j];
break ;
case 2:
current = c[j];
break ;
}
if (j == n - 1) {
dp[i][j][x] = current;
} else if (x == 0) {
dp[i][j][x] = current + dp[i][j + 1][x];
} else {
let nextMax = 0;
for (let next = 0; next < M; next++) {
if (next != i) {
nextMax = Math.max(nextMax, dp[next][j + 1][x - 1]);
} else {
nextMax = Math.max(nextMax, dp[next][j + 1][x]);
}
}
dp[i][j][x] = current + nextMax;
}
}
}
}
let maxSum = 0;
for (let i = 0; i < M; i++) {
maxSum = Math.max(maxSum, dp[i][0][k]);
}
console.log(maxSum);
}
const n = 5;
const k = 1;
const A = [4, 5, 1, 2, 10];
const B = [9, 7, 3, 20, 16];
const C = [6, 12, 13, 9, 8];
findMaxSum(A, B, C, n, k);
|
Output:
67
Time Complexity: O(M * N * K)
Auxiliary Space: O(M * N * K)
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!
Last Updated :
14 Oct, 2023
Like Article
Save Article