Maximum score assigned to a subsequence of numerically consecutive and distinct array elements
Given two arrays arr[] and brr[] of size N such that the array brr[] consists of scores associated with corresponding elements of the array arr[]. The task is to find the maximum possible sum of assigned scores of a subsequence of numerically consecutive and distinct elements of the array arr[].
Examples:
Input: arr[] = {1, 2, 3, 3, 3, 1}, brr[] = {-1, 2, 10, 20, -10, -9}
Output: 22
Explanation:
Distinct values from the array = {1, 2, 3}
Maximum value assigned to each element = {1: -1, 2: 2, 3: 20}
Select the elements at index 2 and 4 in arr[] which are {2, 3}.
Maximum score = 2 + 20 = 22.
Input: arr[] = {1, 2, 3, 2, 3, 1}, brr[] = {-1, 2, 10, 20, -10, -9}
Output: 32
Explanation: Selected subsequence is {arr[1], arr[2], arr[3]} = {2, 3, 2}
Naive Approach: The simplest approach to solve the problem is to use recursion. Follow the steps below to solve the problem:
- Generate all possible subsets of the given array arr[] such that the subset has unique and consecutive elements.
- While generating the subsets in the above step, there are two possibilities for every element of either being added to the subsequence or not. Therefore, follow the steps:
- If the current element is differed by 1 from the previously selected element, add the element to the subsequence.
- Otherwise, proceed to the next element.
- Update the maximum_score by considering both the above two possibilities.
- Print the final value of maximum_score obtained after the complete traversal of the array.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maximumSum( int a[], int b[], int n,
int index, int lastpicked)
{
if (index == n)
return 0;
int option1 = 0, option2 = 0;
if (lastpicked == -1 ||
a[lastpicked] != a[index])
option1 = b[index] + maximumSum(
a, b, n,
index + 1,
index);
option2 = maximumSum(a, b, n,
index + 1,
lastpicked);
return max(option1, option2);
}
int main()
{
int arr[] = { 1, 2, 3, 3, 3, 1 };
int brr[] = { -1, 2, 10, 20, -10, -9 };
int N = sizeof (arr) / sizeof (arr[0]);
cout << (maximumSum(arr, brr, N, 0, -1));
}
|
Java
import java.io.*;
class GFG {
public static int maximumSum(
int [] a, int [] b, int n, int index,
int lastpicked)
{
if (index == n)
return 0 ;
int option1 = 0 , option2 = 0 ;
if (lastpicked == - 1
|| a[lastpicked] != a[index])
option1
= b[index]
+ maximumSum(a, b, n,
index + 1 ,
index);
option2 = maximumSum(a, b, n,
index + 1 ,
lastpicked);
return Math.max(option1, option2);
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 , 3 , 3 , 1 };
int brr[] = { - 1 , 2 , 10 , 20 , - 10 , - 9 };
int N = arr.length;
System.out.println(
maximumSum(arr, brr,
N, 0 , - 1 ));
}
}
|
Python3
def maximumSum(a, b, n, index, lastpicked):
if (index = = n):
return 0
option1 = 0
option2 = 0
if (lastpicked = = - 1 or
a[lastpicked] ! = a[index]):
option1 = b[index] + maximumSum(a, b, n,
index + 1 ,
index)
option2 = maximumSum(a, b, n, index + 1 ,
lastpicked)
return max (option1, option2)
if __name__ = = '__main__' :
arr = [ 1 , 2 , 3 , 3 , 3 , 1 ]
brr = [ - 1 , 2 , 10 , 20 , - 10 , - 9 ]
N = len (arr)
print (maximumSum(arr, brr, N, 0 , - 1 ))
|
C#
using System;
class GFG{
public static int maximumSum( int [] a, int [] b,
int n, int index,
int lastpicked)
{
if (index == n)
return 0;
int option1 = 0, option2 = 0;
if (lastpicked == -1 ||
a[lastpicked] != a[index])
option1 = b[index] + maximumSum(a, b, n,
index + 1,
index);
option2 = maximumSum(a, b, n,
index + 1,
lastpicked);
return Math.Max(option1, option2);
}
public static void Main(String[] args)
{
int []arr = {1, 2, 3, 3, 3, 1};
int []brr = {-1, 2, 10, 20, -10, -9};
int N = arr.Length;
Console.WriteLine(maximumSum(arr, brr,
N, 0, -1));
}
}
|
Javascript
<script>
function maximumSum(
a, b, n, index,
lastpicked)
{
if (index == n)
return 0;
let option1 = 0, option2 = 0;
if (lastpicked == -1
|| a[lastpicked] != a[index])
option1
= b[index]
+ maximumSum(a, b, n,
index + 1,
index);
option2 = maximumSum(a, b, n,
index + 1,
lastpicked);
return Math.max(option1, option2);
}
let arr = [ 1, 2, 3, 3, 3, 1 ];
let brr = [ -1, 2, 10, 20, -10, -9 ];
let N = arr.length;
document.write(
maximumSum(arr, brr,
N, 0, -1));
</script>
|
Time Complexity: O(2N)
Auxiliary Space: O(2N)
Efficient Approach: The above approach can be optimized by using Dynamic Programming as the problem has Overlapping Subproblems. Below are the steps:
- Initialize index as 0 and lastPicked as -1.
- Initialize a 2D array say dp[][] to store the result of the subproblems.
- The states of dp[][] will be the current index and last picked integer.
- Calculate the score for both possible options:
- Select the current element if the last picked integer is different from the current integer.
- Skip the current element and move on to the next element.
- Store the current state as the maximum of the value calculated above two-state.
- Print the value of dp[index][lastPicked + 1] as the result after all the recursive calls end.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maximumSum( int a[], int b[], int n,
int index, int lastpicked,
vector<vector< int >> dp)
{
if (index == n)
return 0;
if (dp[index][lastpicked + 1] != -1)
return dp[index][lastpicked + 1];
int option1 = 0, option2 = 0;
if (lastpicked == -1 ||
a[lastpicked] != a[index])
{
option1 = b[index] + maximumSum(a, b, n,
index + 1,
index, dp);
}
option2 = maximumSum(a, b, n,
index + 1,
lastpicked, dp);
return dp[index][lastpicked + 1] = max(option1,
option2);
}
void maximumPoints( int arr[], int brr[], int n)
{
int index = 0, lastPicked = -1;
vector<vector< int >> dp(n + 5, vector< int >(n + 5, -1));
cout << maximumSum(arr, brr, n, index,
lastPicked, dp)
<< endl;
}
int main()
{
int arr[] = { 1, 2, 3, 3, 3, 1 };
int brr[] = { -1, 2, 10, 20, -10, -9 };
int N = sizeof (arr) / sizeof (arr[0]);
maximumPoints(arr, brr, N);
return 0;
}
|
Java
import java.util.*;
class GFG {
public static int maximumSum(
int [] a, int [] b, int n, int index,
int lastpicked, int [][] dp)
{
if (index == n)
return 0 ;
if (dp[index][lastpicked + 1 ] != - 1 )
return dp[index][lastpicked + 1 ];
int option1 = 0 , option2 = 0 ;
if (lastpicked == - 1
|| a[lastpicked] != a[index]) {
option1 = b[index]
+ maximumSum(a, b, n,
index + 1 ,
index, dp);
}
option2 = maximumSum(a, b, n,
index + 1 ,
lastpicked, dp);
return dp[index][lastpicked + 1 ]
= Math.max(option1, option2);
}
public static void maximumPoints(
int arr[], int brr[], int n)
{
int index = 0 , lastPicked = - 1 ;
int dp[][] = new int [n + 5 ][n + 5 ];
for ( int i[] : dp)
Arrays.fill(i, - 1 );
System.out.println(
maximumSum(arr, brr, n,
index, lastPicked, dp));
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 , 3 , 3 , 1 };
int brr[] = { - 1 , 2 , 10 , 20 , - 10 , - 9 };
int N = arr.length;
maximumPoints(arr, brr, N);
}
}
|
Python3
def maximumSum(a, b, n, index,
lastpicked, dp):
if (index = = n):
return 0
if (dp[index][lastpicked + 1 ] ! = - 1 ):
return dp[index][lastpicked + 1 ]
option1, option2 = 0 , 0
if (lastpicked = = - 1 or
a[lastpicked] ! = a[index]):
option1 = (b[index] +
maximumSum(a, b, n,
index + 1 ,
index, dp))
option2 = maximumSum(a, b, n,
index + 1 ,
lastpicked, dp)
dp[index][lastpicked + 1 ] = max (option1,
option2)
return dp[index][lastpicked + 1 ]
def maximumPoints(arr, brr, n):
index = 0
lastPicked = - 1
dp = [[ - 1 for x in range (n + 5 )]
for y in range (n + 5 )]
print (maximumSum(arr, brr,
n, index,
lastPicked, dp))
if __name__ = = "__main__" :
arr = [ 1 , 2 , 3 , 3 , 3 , 1 ]
brr = [ - 1 , 2 , 10 , 20 , - 10 , - 9 ]
N = len (arr)
maximumPoints(arr, brr, N)
|
C#
using System;
class GFG{
public static int maximumSum( int [] a, int [] b,
int n, int index,
int lastpicked,
int [,] dp)
{
if (index == n)
return 0;
if (dp[index, lastpicked + 1] != -1)
return dp[index, lastpicked + 1];
int option1 = 0, option2 = 0;
if (lastpicked == -1 ||
a[lastpicked] != a[index])
{
option1 = b[index] + maximumSum(a, b, n,
index + 1,
index, dp);
}
option2 = maximumSum(a, b, n,
index + 1,
lastpicked, dp);
return dp[index, lastpicked + 1] =
Math.Max(option1, option2);
}
public static void maximumPoints( int []arr,
int []brr,
int n)
{
int index = 0, lastPicked = -1;
int [,]dp = new int [n + 5, n + 5];
for ( int i = 0; i < n + 5; i++)
{
for ( int j = 0; j < n + 5; j++)
{
dp[i, j] = -1;
}
}
Console.WriteLine(maximumSum(arr, brr, n,
index, lastPicked,
dp));
}
public static void Main(String[] args)
{
int []arr = {1, 2, 3, 3, 3, 1};
int []brr = {-1, 2, 10, 20, -10, -9};
int N = arr.Length;
maximumPoints(arr, brr, N);
}
}
|
Javascript
<script>
function maximumSum(
a, b, n, index,
lastpicked, dp)
{
if (index == n)
return 0;
if (dp[index][lastpicked + 1] != -1)
return dp[index][lastpicked + 1];
let option1 = 0, option2 = 0;
if (lastpicked == -1
|| a[lastpicked] != a[index]) {
option1 = b[index]
+ maximumSum(a, b, n,
index + 1,
index, dp);
}
option2 = maximumSum(a, b, n,
index + 1,
lastpicked, dp);
return dp[index][lastpicked + 1]
= Math.max(option1, option2);
}
function maximumPolets(
arr, brr, n)
{
let index = 0, lastPicked = -1;
let dp = new Array(n + 5);
for ( var i = 0; i < dp.length; i++) {
dp[i] = new Array(2);
}
for ( var i = 0; i < dp.length; i++) {
for ( var j = 0; j < dp.length; j++) {
dp[i][j] = -1;
}
}
document.write(
maximumSum(arr, brr, n,
index, lastPicked, dp));
}
let arr = [ 1, 2, 3, 3, 3, 1 ];
let brr = [ -1, 2, 10, 20, -10, -9 ];
let N = arr.length;
maximumPolets(arr, brr, N);
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(N2)
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 table DP to store the solution of the subproblems and initialize it with 0.
- Initialize the table with base cases.
- Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP.
- Initialize a variable maxScore with 0 because it compare and store maximum value.
- Now iterate over dp and get the maximum value and store it in maxScore.
- At last print the final solution stored in maxScore.
Implementation :
C++
#include <bits/stdc++.h>
using namespace std;
void maximumPoints( int arr[], int brr[], int n)
{
int dp[n + 5][n + 5];
memset (dp, 0, sizeof (dp));
for ( int i = 1; i <= n; i++) {
for ( int j = 0; j < i; j++) {
if (j == 0 || arr[j - 1] != arr[i - 1]) {
dp[i][j] = max(dp[i][j], dp[j][0] + brr[i - 1]);
}
dp[i][i - 1] = max(dp[i][i - 1], dp[j][i - j - 1]);
}
}
int maxScore = 0;
for ( int i = 0; i <= n; i++) {
for ( int j = 0; j <= n; j++) {
maxScore = max(maxScore, dp[i][j]);
}
}
cout << maxScore << endl;
}
int main()
{
int arr[] = { 1, 2, 3, 3, 3, 1 };
int brr[] = { -1, 2, 10, 20, -10, -9 };
int N = sizeof (arr) / sizeof (arr[0]);
maximumPoints(arr, brr, N);
return 0;
}
|
Python3
def maximumPoints(arr, brr, n):
dp = [[ 0 for j in range (n + 5 )] for i in range (n + 5 )]
for i in range ( 1 , n + 1 ):
for j in range (i):
if j = = 0 or arr[j - 1 ] ! = arr[i - 1 ]:
dp[i][j] = max (dp[i][j], dp[j][ 0 ] + brr[i - 1 ])
dp[i][i - 1 ] = max (dp[i][i - 1 ], dp[j][i - j - 1 ])
maxScore = 0
for i in range (n + 1 ):
for j in range (n + 1 ):
maxScore = max (maxScore, dp[i][j])
print (maxScore)
arr = [ 1 , 2 , 3 , 3 , 3 , 1 ]
brr = [ - 1 , 2 , 10 , 20 , - 10 , - 9 ]
N = len (arr)
maximumPoints(arr, brr, N)
|
C#
using System;
public class Program
{
public static void MaximumPoints( int [] arr, int [] brr,
int n)
{
int [, ] dp = new int [n + 5, n + 5];
for ( int i = 0; i < n + 5; i++) {
for ( int j = 0; j < n + 5; j++) {
dp[i, j] = 0;
}
}
for ( int i = 1; i <= n; i++) {
for ( int j = 0; j < i; j++) {
if (j == 0 || arr[j - 1] != arr[i - 1]) {
dp[i, j] = Math.Max(
dp[i, j], dp[j, 0] + brr[i - 1]);
}
dp[i, i - 1] = Math.Max(dp[i, i - 1],
dp[j, i - j - 1]);
}
}
int maxScore = 0;
for ( int i = 0; i <= n; i++) {
for ( int j = 0; j <= n; j++) {
maxScore = Math.Max(maxScore, dp[i, j]);
}
}
Console.WriteLine(maxScore);
}
public static void Main()
{
int [] arr = { 1, 2, 3, 3, 3, 1 };
int [] brr = { -1, 2, 10, 20, -10, -9 };
int n = arr.Length;
MaximumPoints(arr, brr, n);
}
}
|
Javascript
function maximumPoints(arr, brr, n) {
const dp = Array.from({
length: n + 5
}, () => Array(n + 5).fill(0));
for (let i = 1; i <= n; i++) {
for (let j = 0; j < i; j++) {
if (j === 0 || arr[j - 1] !== arr[i - 1]) {
dp[i][j] = Math.max(dp[i][j], dp[j][0] + brr[i - 1]);
}
dp[i][i - 1] = Math.max(dp[i][i - 1], dp[j][i - j - 1]);
}
}
let maxScore = 0;
for (let i = 0; i <= n; i++) {
for (let j = 0; j <= n; j++) {
maxScore = Math.max(maxScore, dp[i][j]);
}
}
console.log(maxScore);
}
const arr = [1, 2, 3, 3, 3, 1];
const brr = [-1, 2, 10, 20, -10, -9];
const n = arr.length;
maximumPoints(arr, brr, n);
|
Java
import java.util.*;
class Main {
static void maximumPoints( int arr[], int brr[], int n)
{
int dp[][] = new int [n + 5 ][n + 5 ];
for ( int i = 0 ; i < n + 5 ; i++) {
Arrays.fill(dp[i], 0 );
}
for ( int i = 1 ; i <= n; i++) {
for ( int j = 0 ; j < i; j++) {
if (j == 0 || arr[j - 1 ] != arr[i - 1 ]) {
dp[i][j] = Math.max(
dp[i][j], dp[j][ 0 ] + brr[i - 1 ]);
}
dp[i][i - 1 ] = Math.max(dp[i][i - 1 ],
dp[j][i - j - 1 ]);
}
}
int maxScore = 0 ;
for ( int i = 0 ; i <= n; i++) {
for ( int j = 0 ; j <= n; j++) {
maxScore = Math.max(maxScore, dp[i][j]);
}
}
System.out.println(maxScore);
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 , 3 , 3 , 1 };
int brr[] = { - 1 , 2 , 10 , 20 , - 10 , - 9 };
int N = arr.length;
maximumPoints(arr, brr, N);
}
}
|
Time Complexity: O(N*N)
Auxiliary Space: O(N*N)
Last Updated :
14 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...