Open in App
Not now

# Find maximum score by performing given operations

• Difficulty Level : Hard
• Last Updated : 31 Jan, 2023

Given two arrays a[] and b[][2] with both having size N. N operations have to be performed, and initially counter will be 0. Additionally, there is a M bonus score for a hitting streak of b[i][0] and the bonus score received will be b[i][1], the task is to find the maximum score by performing either of the below operations optimally for all i from 1 to N.

• Operation 1: increases the counter’s value by 1 and receives a[i] score
• Operation 2: resets the counter’s value to 0, without receiving any score.

Examples:

Input: a[] = {2, 7, 1, 8, 2, 8}, b[][2] = {{2, 10}, {3, 1}, {5, 5}}
Output: 48
Explanation:

• For i = 1, Change the counter’s value from 0 to 1 and receive a 2 score.
• For i = 2, Change the counter’s value from 1 to 2 and receive a 7 score and get 10 scores as a streak bonus as well.
• For i = 3, Change the counter’s value from 2 to 0.
• For i = 4, Change the counter’s value from 0 to 1 and receive 8 scores.
• For i = 5, Change the counter’s value from 1 to 2 and receive 2 scores and get a 10 score as a streak bonus.
• For i = 6, Change the counter’s value from 2 to 3 and receive 8 scores. and get 1 score as a streak bonus.

Total score : 2 + 7 + 10 + 8 + 2 +10 + 8 +1 = 48.

Input:  a[] = {1000000000, 1000000000, 1000000000}, b[][2] = {{1, 1000000000}, {3, 1000000000}}
Output: 5000000000

Naive approach: The problem can be solved based on The basis of the following idea:

Basic way to solve this problem is to generate all 2N combinations by recursive brute force.

Time Complexity: O(2N)
Auxiliary Space: O(1)

Efficient Approach:  The above approach can be optimized based on the following idea:

Dynamic programming along with hashing can be used to solve to this problem.

• dp[i][j] represents maximum score till i’th operation with current counter j.
• recurrence relation: dp[i][j] = max(dp[i  – 1][j + 1] + a[i] + hash[j + 1], dp[i – 1][0])

It can be observed that there are N * N states but the recursive function is called exponential times. That means that some states are called repeatedly. So the idea is to store the value of states. This can be done using recursive structure intact and just store the value in a HashMap and whenever the function is called, return the value store without computing .

Follow the steps below to solve the problem:

• Creating a hashmap array for mapping values of b[i][0] to b[i][1] named hash[].
• Create a recursive function that takes two parameters i representing i’th operation and j representing counter at i’th operation.
• Call the recursive function for both increasing the current counter by 1 and resetting the counter.
• Check the base case if all N operations are over then return 0.
• Create a 2d array of dp[5001][5001] initially filled with -1.
• If the answer for a particular state is computed then save it in dp[i][j].
• If the answer for a particular state is already computed then just return dp[i][j].

Below is the implementation of the above approach.

## C++

 `// C++ code to implement the approach` `#include ` `using` `namespace` `std;`   `// To avoid integer overflow` `#define int long long`   `// dp table initialized with - 1` `int` `dp[5001][5001];`   `// Recursive function to count maximum score` `// by performing following operations` `int` `recur(``int` `i, ``int` `j, ``int` `a[], ``int` `hash[], ``int` `N)` `{`   `    ``// Base case` `    ``if` `(i == N) {` `        ``return` `0;` `    ``}`   `    ``// If answer for current state is already` `    ``// calculated then just return dp[i][j]` `    ``if` `(dp[i][j] != -1)` `        ``return` `dp[i][j];`   `    ``// Calling recursive function for` `    ``// performing operation 1` `    ``int` `ans = recur(i + 1, j + 1, a, hash, N) + a[i]` `              ``+ hash[j + 1];`   `    ``// Calling recursive function for` `    ``// performing operation 2` `    ``ans = max(ans, recur(i + 1, 0, a, hash, N) + 0LL);`   `    ``// Save and return dp value` `    ``return` `dp[i][j] = ans;` `}`   `// Function to count maximum score` `// by performing following operations` `void` `findMaximumScore(``int` `a[], ``int` `b[][2], ``int` `N, ``int` `M)` `{`   `    ``// Filling dp table with -1` `    ``memset``(dp, -1, ``sizeof``(dp));`   `    ``// Creating Hash table` `    ``int` `hash[N + 1] = { 0 };`   `    ``// Mapping hash table with values` `    ``for` `(``int` `i = 0; i < M; i++) {` `        ``hash[b[i][0]] += b[i][1];` `    ``}`   `    ``cout << recur(0, 0, a, hash, N) << endl;` `}`   `// Driver Code` `int32_t main()` `{`   `    ``// Input 1` `    ``int` `a[] = { 2, 7, 1, 8, 2, 8 },` `        ``b[][2] = { { 2, 10 }, { 3, 1 }, { 5, 5 } };` `    ``int` `N = ``sizeof``(a) / ``sizeof``(a[0]);` `    ``int` `M = ``sizeof``(b) / ``sizeof``(b[0]);`   `    ``// Function Call` `    ``findMaximumScore(a, b, N, M);`   `    ``// Input 2` `    ``int` `a1[] = { 1000000000, 1000000000, 1000000000 },` `        ``b1[][2] = { { 1, 1000000000 }, { 3, 1000000000 } };` `    ``int` `N1 = ``sizeof``(a1) / ``sizeof``(a1[0]);` `    ``int` `M1 = ``sizeof``(b1) / ``sizeof``(b1[0]);`   `    ``// Function Call` `    ``findMaximumScore(a1, b1, N1, M1);` `    ``return` `0;` `}`

## Java

 `// Java code for the above approach` `import` `java.util.Arrays;`   `class` `Main ` `{` `  `  `    ``// To avoid integer overflow` `    ``static` `long` `MAX = ``1000000007``;`   `    ``// dp table initialized with - 1` `    ``static` `long``[][] dp = ``new` `long``[``5001``][``5001``];`   `    ``// Recursive function to count maximum score` `    ``// by performing following operations` `    ``static` `long` `recur(``int` `i, ``int` `j, ``int``[] a, ``int``[] hash, ``int` `N) ` `    ``{` `      `  `        ``// Base case` `        ``if` `(i == N) {` `            ``return` `0``;` `        ``}`   `        ``// If answer for current state is already` `        ``// calculated then just return dp[i][j]` `        ``if` `(dp[i][j] != -``1``) {` `            ``return` `dp[i][j];` `        ``}`   `        ``// Calling recursive function for` `        ``// performing operation 1` `        ``long` `ans = recur(i + ``1``, j + ``1``, a, hash, N) + a[i]` `                ``+ hash[j + ``1``];`   `        ``// Calling recursive function for` `        ``// performing operation 2` `        ``ans = Math.max(ans, recur(i + ``1``, ``0``, a, hash, N) + ``0``);`   `        ``// Save and return dp value` `        ``return` `dp[i][j] = ans;` `    ``}`   `    ``// Function to count maximum score` `    ``// by performing following operations` `    ``static` `void` `findMaximumScore(``int``[] a, ``int``[][] b, ``int` `N, ``int` `M) ` `    ``{` `      `  `        ``// Filling dp table with -1` `        ``for` `(``long``[] row : dp) {` `            ``Arrays.fill(row, -``1``);` `        ``}`   `        ``// Creating Hash table` `        ``int``[] hash = ``new` `int``[N + ``1``];`   `        ``// Mapping hash table with values` `        ``for` `(``int` `i = ``0``; i < M; i++) {` `            ``hash[b[i][``0``]] += b[i][``1``];` `        ``}`   `        ``System.out.println(recur(``0``, ``0``, a, hash, N));` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `main(String[] args) {` `        ``// Input 1` `        ``int``[] a = { ``2``, ``7``, ``1``, ``8``, ``2``, ``8` `};` `        ``int``[][] b = { { ``2``, ``10` `}, { ``3``, ``1` `}, { ``5``, ``5` `} };` `        ``int` `N = a.length;` `        ``int` `M = b.length;`   `        ``// Function Call` `        ``findMaximumScore(a, b, N, M);`   `        ``// Input 2` `        ``int``[] a1 = { ``1000000000``, ``1000000000``, ``1000000000` `};` `        ``int``[][] b1 = { { ``1``, ``1000000000` `}, { ``3``, ``1000000000` `} };` `        ``int` `N1 = a1.length;` `        ``int` `M1 = b1.length;`   `        ``// Function Call` `        ``findMaximumScore(a1, b1, N1, M1);` `    ``}` `}`   `// This code is contributed by Potta Lokesh`

## Python3

 `#Python code to implement the approach`   `# dp table initialized with - 1` `dp``=``[[``-``1` `for` `i ``in` `range``(``5001``)] ``for` `j ``in` `range``(``5001``)]`   `# Recursive function to count maximum score` `# by performing following operations` `def` `recur(i,j,a,``hash``,N):` `    ``# Base case` `    ``if``(i``=``=``N):` `        ``return` `0` `        `  `    ``# If answer for current state is already` `    ``# calculated then just return dp[i][j]` `    ``if``(dp[i][j]!``=``-``1``):` `        ``return` `dp[i][j]` `        `  `    ``# Calling recursive function for` `    ``# performing operation 1` `    ``ans``=``recur(i``+``1``,j``+``1``,a,``hash``,N)``+``a[i]``+``hash``[j``+``1``]` `    `  `    ``# Calling recursive function for` `    ``# performing operation 2` `    ``ans``=``max``(ans,recur(i``+``1``,``0``,a,``hash``,N))` `    `  `    ``# Save and return dp value` `    ``dp[i][j]``=``ans` `    ``return` `dp[i][j]`   `# Function to count maximum score` `# by performing following operations` `def` `findMaximumScore(a,b,N,M):` `    `  `    ``# Filling dp table with -1` `    ``for` `i ``in` `range``(``len``(dp)):` `        ``for` `j ``in` `range``(``len``(dp[``0``])):` `            ``dp[i][j]``=``-``1` `    `  `    ``# Creating Hash table` `    ``hash``=``[``0``]``*``(N``+``1``)` `    `  `    ``# Mapping hash table with values` `    ``for` `i ``in` `range``(M):` `        ``hash``[b[i][``0``]]``+``=``b[i][``1``]` `    `  `    ``print``(recur(``0``,``0``,a,``hash``,N))` `    `  `# Driver Code`   `# Input 1` `a``=``[``2``, ``7``, ``1``, ``8``, ``2``, ``8``]` `b``=``[[``2``,``10``],[``3``,``1``],[``5``,``5``]]` `N``=``len``(a)` `M``=``len``(b)`   `# Function call` `findMaximumScore(a,b,N,M)`   `# Input 2` `a1``=``[``1000000000``, ``1000000000``, ``1000000000``]` `b1``=``[[``1``,``1000000000``],[``3``,``1000000000``]]` `N1``=``len``(a1)` `M1``=``len``(b1)`   `# Function call` `findMaximumScore(a1,b1,N1,M1)`   `# This code is contributed by Pushpesh Raj.`

## C#

 `using` `System;` `using` `System.Linq;`   `class` `GFG` `{` `  `  `  ``// To avoid integer overflow` `  ``static` `long` `MAX = 1000000007;`   `  ``// dp table initialized with - 1` `  ``static` `long``[, ] dp = ``new` `long``[5001, 5001];`   `  ``// Recursive function to count maximum score` `  ``// by performing following operations` `  ``static` `long` `recur(``int` `i, ``int` `j, ``int``[] a, ``int``[] hash,` `                    ``int` `N)` `  ``{`   `    ``// Base case` `    ``if` `(i == N) {` `      ``return` `0;` `    ``}`   `    ``// If answer for current state is already` `    ``// calculated then just return dp[i][j]` `    ``if` `(dp[i, j] != -1) {` `      ``return` `dp[i, j];` `    ``}`   `    ``// Calling recursive function for` `    ``// performing operation 1` `    ``long` `ans = recur(i + 1, j + 1, a, hash, N) + a[i]` `      ``+ hash[j + 1];`   `    ``// Calling recursive function for` `    ``// performing operation 2` `    ``ans = Math.Max(ans,` `                   ``recur(i + 1, 0, a, hash, N) + 0);`   `    ``// Save and return dp value` `    ``return` `dp[i, j] = ans;` `  ``}`   `  ``// Function to count maximum score` `  ``// by performing following operations` `  ``static` `void` `findMaximumScore(``int``[] a, ``int``[, ] b, ``int` `N,` `                               ``int` `M)` `  ``{`   `    ``// Filling dp table with -1` `    ``for` `(``int` `i = 0; i < 5001; i++) {` `      ``for` `(``int` `j = 0; j < 5001; j++) {` `        ``dp[i, j] = -1;` `      ``}` `    ``}`   `    ``// Creating Hash table` `    ``int``[] hash = ``new` `int``[N + 1];`   `    ``// Mapping hash table with values` `    ``for` `(``int` `i = 0; i < M; i++) {` `      ``hash[b[i, 0]] += b[i, 1];` `    ``}`   `    ``Console.WriteLine(recur(0, 0, a, hash, N));` `  ``}`   `  ``// Driver Code` `  ``public` `static` `void` `Main(``string``[] args)` `  ``{` `    ``// Input 1` `    ``int``[] a = { 2, 7, 1, 8, 2, 8 };` `    ``int``[, ] b = { { 2, 10 }, { 3, 1 }, { 5, 5 } };` `    ``int` `N = a.Length;` `    ``int` `M = b.GetLength(0);`   `    ``// Function Call` `    ``findMaximumScore(a, b, N, M);`   `    ``// Input 2` `    ``int``[] a1 = { 1000000000, 1000000000, 1000000000 };` `    ``int``[, ] b1` `      ``= { { 1, 1000000000 }, { 3, 1000000000 } };` `    ``int` `N1 = a1.Length;` `    ``int` `M1 = b1.GetLength(0);`   `    ``// Function Call` `    ``findMaximumScore(a1, b1, N1, M1);` `  ``}` `}`   `// This code is contributed by ik_9`

## Javascript

 `// Javascript code to implement the approach`   `// dp table initialized with - 1` `let dp=``new` `Array(5001);` `for``(let i=0; i<5001; i++)` `    ``dp[i]=``new` `Array(5001);`   `// Recursive function to count maximum score` `// by performing following operations` `function` `recur(i, j, a, hash, N)` `{`   `    ``// Base case` `    ``if` `(i == N) {` `        ``return` `0;` `    ``}`   `    ``// If answer for current state is already` `    ``// calculated then just return dp[i][j]` `    ``if` `(dp[i][j] != -1)` `        ``return` `dp[i][j];`   `    ``// Calling recursive function for` `    ``// performing operation 1` `    ``let ans = recur(i + 1, j + 1, a, hash, N) + a[i]` `              ``+ hash[j + 1];`   `    ``// Calling recursive function for` `    ``// performing operation 2` `    ``ans = Math.max(ans, recur(i + 1, 0, a, hash, N) + 0);`   `    ``// Save and return dp value` `    ``return` `dp[i][j] = ans;` `}`   `// Function to count maximum score` `// by performing following operations` `function` `findMaximumScore(a, b, N, M)` `{`   `    ``// Filling dp table with -1` `    ``for``(let i=0; i<5001; i++)` `        ``for``(let j=0; j<5001; j++)` `            ``dp[i][j]=-1;` `            `  `    ``// Creating Hash table` `    ``let hash = ``new` `Array(N+1).fill(0);`   `    ``// Mapping hash table with values` `    ``for` `(let i = 0; i < M; i++) {` `        ``hash[b[i][0]] += b[i][1];` `    ``}`   `    ``document.write(recur(0, 0, a, hash, N))` `}`   `// Driver Code` `    ``// Input 1` `    ``let a = [ 2, 7, 1, 8, 2, 8 ],` `        ``b = [[ 2, 10 ], [ 3, 1 ], [ 5, 5 ]];` `    ``let N = a.length;` `    ``let M = b.length;`   `    ``// Function Call` `    ``findMaximumScore(a, b, N, M);` `    `  `    ``document.write(``"
"``);`   `    ``// Input 2` `    ``let a1 = [ 1000000000, 1000000000, 1000000000 ],` `        ``b1 = [ [ 1, 1000000000 ], [ 3, 1000000000 ] ];` `    ``let N1 = a1.length;` `    ``let M1 = b1.length;`   `    ``// Function Call` `    ``findMaximumScore(a1, b1, N1, M1);`

Output

```48
5000000000```

Time Complexity: O(N2)
Auxiliary Space: O(N2)

Related Articles:

My Personal Notes arrow_drop_up
Related Articles