Maximize sum of selected integers from an Array of pair of integers as per given condition
Given an array arr[] having N pair of integers of the form (x, y), the task is to maximize the sum y values in selected pairs such that if a pair (xi, yi) is selected, the next xi pairs cannot be selected.
Examples:
Input: arr[]= {{1, 5}, {2, 7}, {1, 4}, {1, 5}, {1, 10}}
Output: 19
Explanation: Choose the pair at the index i = 0 i.e, (1, 5). Hence the next 1 pair cannot be selected. Similarly, select the pairs at index 2 and 4 i.e, (1, 4) and (1, 10). Therefore, the sum of all the y values of the selected pairs is 5+4+10 = 19, which is the maximum possible.
Input: arr[] = {{1, 5}, {2, 10}, {3, 3}, {7, 4}}
Output: 10
Recursive Approach:
We start with the first element of the array, and for each element, we have two choices: either we select it or we don’t select it. If we select an element, we cannot select its adjacent element. Therefore, we skip the next element and recursively call the function for the remaining elements. If we don’t select an element, we move on to the next element and recursively call the function for the remaining elements.
The base case for this recursion is when we reach the end of the array. If we have reached the end of the array, we return 0. Otherwise, we compare the maximum sum we get if we select the current element with the maximum sum we get if we don’t select the current element, and we return the larger of the two.
Algorithm:
- Initialize an integer n with the size of the input array.
- Define a recursive function solve that takes three parameters: the input array arr, the current index idx, and the size of the input array n.
- In the solve function, check if the current index idx is greater than or equal to n. If it is, return 0.
- If the current index is n-1, return the y value of the pair.
- Calculate the maximum possible sum for the current index using the recurrence relation:
ans = max(solve(arr, idx + 1, n), solve(arr, idx + arr[idx].first + 1, n) + arr[idx].second)
- Return the value of ans.
- Call the solve function with arr, 0, and n as arguments and store the result in ans.
- Output the result.
Below is the implementation of the approach:
C++
#include <bits/stdc++.h>
using namespace std;
int solve(vector<pair< int , int >>& arr, int idx, int n)
{
if (idx >= n) {
return 0;
}
if (idx == n - 1)
return arr[n - 1].second;
int ans
= max(solve(arr, idx + 1, n),
solve(arr, idx + arr[idx].first + 1, n)
+ arr[idx].second);
return ans;
}
int main()
{
vector<pair< int , int >> arr = {
{ 1, 5 }, { 2, 7 }, { 1, 4 }, { 1, 5 }, { 1, 10 }
};
int N = arr.size();
int ans = solve(arr, 0, N);
cout << ans << endl;
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.List;
public class Main {
public static int solve(List<Pair> arr, int idx, int n) {
if (idx >= n) {
return 0 ;
}
if (idx == n - 1 ) {
return arr.get(n - 1 ).y;
}
int ans = Math.max(solve(arr, idx + 1 , n),
solve(arr, idx + arr.get(idx).x + 1 , n) + arr.get(idx).y);
return ans;
}
public static void main(String[] args) {
List<Pair> arr = new ArrayList<>();
arr.add( new Pair( 1 , 5 ));
arr.add( new Pair( 2 , 7 ));
arr.add( new Pair( 1 , 4 ));
arr.add( new Pair( 1 , 5 ));
arr.add( new Pair( 1 , 10 ));
int N = arr.size();
int ans = solve(arr, 0 , N);
System.out.println(ans);
}
static class Pair {
int x;
int y;
Pair( int x, int y) {
this .x = x;
this .y = y;
}
}
}
|
Python3
def solve(arr, idx, n):
if idx > = n:
return 0
if idx = = n - 1 :
return arr[n - 1 ][ 1 ]
ans = max (solve(arr, idx + 1 , n), solve(arr, idx + arr[idx][ 0 ] + 1 , n) + arr[idx][ 1 ])
return ans
if __name__ = = "__main__" :
arr = [( 1 , 5 ), ( 2 , 7 ), ( 1 , 4 ), ( 1 , 5 ), ( 1 , 10 )]
N = len (arr)
ans = solve(arr, 0 , N)
print (ans)
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int Solve(List<Tuple< int , int >> arr, int idx, int n)
{
if (idx >= n)
{
return 0;
}
if (idx == n - 1)
{
return arr[n - 1].Item2;
}
int ans = Math.Max(
Solve(arr, idx + 1, n),
Solve(arr, idx + arr[idx].Item1 + 1, n) + arr[idx].Item2
);
return ans;
}
static void Main()
{
List<Tuple< int , int >> arr = new List<Tuple< int , int >> {
Tuple.Create(1, 5), Tuple.Create(2, 7), Tuple.Create(1, 4),
Tuple.Create(1, 5), Tuple.Create(1, 10)
};
int N = arr.Count;
int ans = Solve(arr, 0, N);
Console.WriteLine(ans);
}
}
|
Javascript
function solve(arr, idx, n) {
if (idx >= n) {
return 0;
}
if (idx === n - 1) {
return arr[n - 1][1];
}
const ans = Math.max(
solve(arr, idx + 1, n),
solve(arr, idx + arr[idx][0] + 1, n) + arr[idx][1]
);
return ans;
}
const arr = [
[1, 5],
[2, 7],
[1, 4],
[1, 5],
[1, 10],
];
const N = arr.length;
const ans = solve(arr, 0, N);
console.log(ans);
|
Time Complexity: O(2^n), since for each element, we are considering two possibilities – either include it in the sum or exclude it from the sum. Since there are n elements, the total number of possible combinations is 2^n.
Auxiliary Space: O(n), since we are only using the call stack space to store the function calls. The maximum depth of the call stack will be n, since we are recursively calling the function for each element of the array.
Memoised Approach:
This approach uses memoised method of dynamic programming to solve the given problem. We first initialize a 1D array dp[] with 0, which stores the maximum possible sum of selected y values for each index i.
We then compute the value of dp[i] for all i in the range [n, 0] by considering two choices:
- Either we skip the i-th pair and consider the maximum possible sum of selected y values for the remaining pairs (i.e., dp[i+1]),
- or we select the i-th pair and consider the maximum possible sum of selected y values for the pairs that come after the next x pairs (i.e., dp[i+arr[i].first+1]+arr[i].second).
Finally, we return the value stored in dp[0], which represents the maximum possible sum of selected y values for the entire array arr[].
Algorithm:
- Initialize an integer n with the size of the input array.
- Initialize a vector of integers dp of size n with -1 to store the subproblem solutions.
- Define a recursive function solve that takes four parameters: the input array arr, the DP array dp, the current index idx, and the size of the input array n.
- In the solve function, check if the current index idx is greater than or equal to n. If it is, return 0.
- If the current index is n-1, return the y value of the pair.
- If the value at current index has already been calculated, return the value.
- Calculate the maximum possible sum for the current index using the recurrence relation:
ans = max(solve(arr, dp, idx + 1, n), solve(arr, dp, idx + arr[idx].first + 1, n) + arr[idx].second)
- Store the value of ans in dp array.
- Return the value of ans.
- Call the solve function with arr, dp, 0, and n as arguments and store the result in ans.
- Output the result.
Below is the implementation of the approach:
C++
#include <bits/stdc++.h>
using namespace std;
int solve(vector<pair< int , int > >& arr, vector< int >& dp,
int idx, int n)
{
if (idx >= n) {
return 0;
}
if (idx == n - 1)
return arr[n - 1].second;
if (dp[idx] != -1) {
return dp[idx];
}
int ans
= max(solve(arr, dp, idx + 1, n),
solve(arr, dp, idx + arr[idx].first + 1, n)
+ arr[idx].second);
dp[idx] = ans;
return ans;
}
int main()
{
vector<pair< int , int > > arr = {
{ 1, 5 }, { 2, 7 }, { 1, 4 }, { 1, 5 }, { 1, 10 }
};
int N = arr.size();
vector< int > dp(N, -1);
int ans = solve(arr, dp, 0, N);
cout << ans << endl;
return 0;
}
|
Java
import java.util.Arrays;
public class MaxSumPairs {
static int solve( int idx, int n, int [] dp, int [][] arr) {
if (idx >= n) {
return 0 ;
}
if (idx == n - 1 )
return arr[n - 1 ][ 1 ];
if (dp[idx] != - 1 ) {
return dp[idx];
}
int ans = Math.max(solve(idx + 1 , n, dp, arr),
solve(idx + arr[idx][ 0 ] + 1 , n, dp, arr)
+ arr[idx][ 1 ]);
dp[idx] = ans;
return ans;
}
public static void main(String[] args) {
int [][] arr = {
{ 1 , 5 }, { 2 , 7 }, { 1 , 4 }, { 1 , 5 }, { 1 , 10 }
};
int N = arr.length;
int [] dp = new int [N];
Arrays.fill(dp, - 1 );
int ans = solve( 0 , N, dp, arr);
System.out.println(ans);
}
}
|
Python
def solve(arr, dp, idx, n):
if idx > = n:
return 0
if idx = = n - 1 :
return arr[n - 1 ][ 1 ]
if dp[idx] ! = - 1 :
return dp[idx]
ans = max (solve(arr, dp, idx + 1 , n),
solve(arr, dp, idx + arr[idx][ 0 ] + 1 , n)
+ arr[idx][ 1 ])
dp[idx] = ans
return ans
if __name__ = = "__main__" :
arr = [( 1 , 5 ), ( 2 , 7 ), ( 1 , 4 ), ( 1 , 5 ), ( 1 , 10 )]
N = len (arr)
dp = [ - 1 ] * N
ans = solve(arr, dp, 0 , N)
print (ans)
|
C#
using System;
using System.Collections.Generic;
class Program {
static int Solve(List<Tuple< int , int > > arr,
List< int > dp, int idx, int n)
{
if (idx >= n) {
return 0;
}
if (idx == n - 1) {
return arr[n - 1].Item2;
}
if (dp[idx] != -1) {
return dp[idx];
}
int ans = Math.Max(
Solve(arr, dp, idx + 1, n),
Solve(arr, dp, idx + arr[idx].Item1 + 1, n)
+ arr[idx].Item2);
dp[idx] = ans;
return ans;
}
static void Main()
{
List<Tuple< int , int > > arr
= new List<Tuple< int , int > >{
Tuple.Create(1, 5), Tuple.Create(2, 7),
Tuple.Create(1, 4), Tuple.Create(1, 5),
Tuple.Create(1, 10)
};
int N = arr.Count;
List< int > dp = new List< int >( new int [N]);
for ( int i = 0; i < N; i++) {
dp[i] = -1;
}
int ans = Solve(arr, dp, 0, N);
Console.WriteLine(ans);
}
}
|
Javascript
function solve(arr, dp, idx, n) {
if (idx >= n) {
return 0;
}
if (idx === n - 1) {
return arr[n - 1][1];
}
if (dp[idx] !== -1) {
return dp[idx];
}
const ans = Math.max(
solve(arr, dp, idx + 1, n),
solve(arr, dp, idx + arr[idx][0] + 1, n) + arr[idx][1]
);
dp[idx] = ans;
return ans;
}
function main() {
const arr = [
[1, 5],
[2, 7],
[1, 4],
[1, 5],
[1, 10]
];
const N = arr.length;
const dp = Array(N).fill(-1);
const ans = solve(arr, dp, 0, N);
console.log(ans);
}
main();
|
Time Complexity: O(N) where N is size of input array.
Auxiliary Space: O(N) as vector dp has been created. Here, n is size of input array.
Approach: The given problem can be solved using dynamic programming. Create an array dp[], where dp[i] represents the maximum possible sum of selected elements of the array arr[] in the range [i, N] and initialize the value of all indices with 0. Hence, the dp[] array can be calculated using the below relation:
dp[i] = max( dp[i + 1], dp[i + xi + 1] + yi)
Therefore, calculate the value for each state in dp[i] for all values of i in the range [N, 0]. The value stored at dp[0] will be the required answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maximizeSum(vector<pair< int , int > > arr, int N)
{
vector< int > dp(N + 1, 0);
dp[N - 1] = arr[N - 1].second;
for ( int i = N - 2; i >= 0; i--) {
if (i + arr[i].first < N)
dp[i] = max(dp[i + 1],
dp[i + arr[i].first + 1]
+ arr[i].second);
else
dp[i] = dp[i + 1];
}
return dp[0];
}
int main()
{
vector<pair< int , int > > arr = {
{ 1, 5 }, { 2, 7 }, { 1, 4 }, { 1, 5 }, { 1, 10 }
};
cout << maximizeSum(arr, arr.size());
return 0;
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
class Pair {
int first;
int second;
public Pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
class GFG {
static int maximizeSum(Pair arr[ ], int N)
{
int dp[] = new int [N + 1 ];
dp[N - 1 ] = arr[N - 1 ].second;
for ( int i = N - 2 ; i >= 0 ; i--) {
if (i + arr[i].first < N)
dp[i] = Math.max(dp[i + 1 ],
dp[i + arr[i].first + 1 ]
+ arr[i].second);
else
dp[i] = dp[i + 1 ];
}
return dp[ 0 ];
}
public static void main (String[] args)
{
int n = 5 ;
Pair arr[] = new Pair[n];
arr[ 0 ] = new Pair( 1 , 5 );
arr[ 1 ] = new Pair( 2 , 7 );
arr[ 2 ] = new Pair( 1 , 4 );
arr[ 3 ] = new Pair( 1 , 5 );
arr[ 4 ] = new Pair( 1 , 10 );
System.out.print(maximizeSum(arr, n));
}
}
|
Python3
def maximizeSum(arr, N):
dp = [ 0 ] * (N + 1 )
dp[N - 1 ] = arr[N - 1 ][ "second" ]
for i in range (N - 2 , - 1 , - 1 ):
if (i + arr[i][ "first" ] < N):
dp[i] = max (dp[i + 1 ],
dp[i + arr[i][ "first" ] + 1 ]
+ arr[i][ "second" ])
else :
dp[i] = dp[i + 1 ]
return dp[ 0 ]
arr = [{ "first" : 1 , "second" : 5 },
{ "first" : 2 , "second" : 7 },
{ "first" : 1 , "second" : 4 },
{ "first" : 1 , "second" : 5 },
{ "first" : 1 , "second" : 10 }
]
print (maximizeSum(arr, len (arr)))
|
C#
using System;
using System.Collections.Generic;
class Pair {
public int first;
public int second;
public Pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
public class GFG {
static int maximizeSum(Pair []arr, int N)
{
int []dp = new int [N + 1];
dp[N - 1] = arr[N - 1].second;
for ( int i = N - 2; i >= 0; i--) {
if (i + arr[i].first < N)
dp[i] = Math.Max(dp[i + 1],
dp[i + arr[i].first + 1]
+ arr[i].second);
else
dp[i] = dp[i + 1];
}
return dp[0];
}
public static void Main(String[] args)
{
int n = 5;
Pair []arr = new Pair[n];
arr[0] = new Pair(1, 5);
arr[1] = new Pair(2, 7);
arr[2] = new Pair(1, 4);
arr[3] = new Pair(1, 5);
arr[4] = new Pair(1, 10);
Console.Write(maximizeSum(arr, n));
}
}
|
Javascript
<script>
function maximizeSum(arr, N)
{
let dp = new Array(N + 1).fill(0);
dp[N - 1] = arr[N - 1].second;
for (let i = N - 2; i >= 0; i--) {
if (i + arr[i].first < N)
dp[i] = Math.max(dp[i + 1],
dp[i + arr[i].first + 1]
+ arr[i].second);
else
dp[i] = dp[i + 1];
}
return dp[0];
}
let arr = [{ first: 1, second: 5 },
{ first: 2, second: 7 },
{ first: 1, second: 4 },
{ first: 1, second: 5 },
{ first: 1, second: 10 }
];
document.write(maximizeSum(arr, arr.length));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Last Updated :
06 Jan, 2024
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...