GFG App
Open App
Browser
Continue

Maximize score by matching element with prediction and K switch are allowed

Given an array arr[] of size N, with values either 1, 2, or 3. Traverse the array from left to right and before traversal predict one number from 1, 2, or 3, if arr[i] is matched with the prediction score will be increased by 1. The prediction can be switched at most K times. Find the maximum score possible.

Examples:

Input: A[] = {1, 1, 2, 1, 3}, K = 1
Output: 4
Explanation:
Following is the optimal way to perform the above operations:
Initially choose P = 1 for the i = 0 as number matches with A[0] = 1, received 1 point.
For i = 1, A[1] = 1 and we did not change chosen number P = 1 , as A[1] and P are equal we received another 1 point.
For i = 2, A[2] = 2 and we did not change chosen number P = 1 so, we do not receive point since P != A[2].
For i = 3, A[3] = 1 and we did  not change chosen number P = 1 so, we receives another one point since P = A[3].
For i = 4, A[4] = 3 and we switch P to 3 since we can make a switch at most K = 1 times. P = 3 and A[4] is also 3 so we receive another point.
With this strategy, we receive a total of 4 points.

Input: A[] = {3, 3, 1, 3, 3, 2, 2, 2 }, K = 0
Output: 4
Explanation: It is optimal to choose 3 for all indices since we cannot make changes once we select a particular number because K = 0.

Naive approach: The basic way to solve the problem is as follows:

The basic way to solve this problem is to explore all possible combinations by using a recursive approach.

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

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

Dynamic programming can be used to solve this problem.

dp[i][j][k] represents the maximum score till ith element with j chosen in the last match along with k switches left.
Recurrence relation is one of the following depending upon the value of K  and we are switching to which number:

• dp[i][j]k] = max(dp[i + 1][1][k] + (A[i] == 1), dp[i + 1][2][k – 1] + (A[i] == 2), dp[i + 1][3][k – 1] + (A[i] == 3))
• dp[i][j]k] = max(dp[i + 1][1][k – 1] + (A[i] == 1), dp[i + 1][2][k] + (A[i] == 2), dp[i + 1][3][k – 1] + (A[i] == 3))
• dp[i][j]k] = max(dp[i + 1][1][k – 1] + (A[i] == 1), dp[i + 1][2][k – 1] + (A[i] == 2), dp[i + 1][3][k] + (A[i] == 3))

It can be observed that the recursive function is called exponential times. That means that some states are called repeatedly. So the idea is to store the value of each state.

Follow the steps below to solve the problem:

• Create a 3d array of dp[N][5][21] initially filled with -1.
• Create a recursive function that takes three parameters i representing ith element,, j representing the last element chosen, and k representing the number of switches left.
• Check the base case, if all matches over return 0.
• If the answer for a particular state is computed then save it in dp[i][j][k].
• Otherwise, call the recursive function three times for choosing all three numbers.
• If the answer for a particular state is already computed then just return dp[i][j][k].

Below is the implementation of the above approach.

C++

 `// C++ code to implement the approach`   `#include ` `using` `namespace` `std;`   `// dp table initialization` `int` `dp[100001][5][21];`   `// Recursive function to calculate maximum` `// score from traversing left to right.` `int` `recur(``int` `i, ``int` `j, ``int` `k, ``int` `A[], ``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][k] != -1)` `        ``return` `dp[i][j + 1][k];`   `    ``int` `ans = INT_MIN;`   `    ``// Calling recursive function for choosing 1` `    ``if` `((k != 0) or (k == 0 and j == 1))` `        ``ans = max(` `            ``ans, recur(i + 1, 1, (j == 1) ? k : k - 1, A, N)` `                     ``+ (A[i] == 1));`   `    ``// Calling recursive function for choosing 2` `    ``if` `((k != 0) or (k == 0 and j == 2))` `        ``ans = max(` `            ``ans, recur(i + 1, 2, (j == 2) ? k : k - 1, A, N)` `                     ``+ (A[i] == 2));`   `    ``// Calling recursive function for choosing 3` `    ``if` `((k != 0) or (k == 0 and j == 3))` `        ``ans = max(` `            ``ans, recur(i + 1, 3, (j == 3) ? k : k - 1, A, N)` `                     ``+ (A[i] == 3));`   `    ``// Save and return dp value` `    ``return` `dp[i][j + 1][k] = ans;` `}`   `// Function to calculate maximum score` `// by traversing left to right` `int` `minCost(``int` `A[], ``int` `N, ``int` `K)` `{` `    ``// Filling dp table with -1` `    ``memset``(dp, -1, ``sizeof``(dp));`   `    ``// Calling the utility function` `    ``return` `recur(0, -1, K + 1, A, N);` `}`   `// Driver Code` `int` `main()` `{` `    ``// Test Case 1` `    ``int` `A[] = { 1, 1, 2, 1, 3 }, K = 1;` `    ``int` `N = ``sizeof``(A) / ``sizeof``(A[0]);`   `    ``// Function Call` `    ``cout << minCost(A, N, K) << endl;`   `    ``// Test Case 2` `    ``int` `A1[] = { 3, 3, 1, 3, 3, 2, 2, 2 }, K1 = 0;` `    ``int` `N1 = ``sizeof``(A1) / ``sizeof``(A1[0]);`   `    ``// Function Call` `    ``cout << minCost(A1, N1, K1) << endl;`   `    ``return` `0;` `}`

Java

 `// Java code to implement the approach` `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG {`   `  ``// dp table initialization` `  ``static` `int``[][][] dp = ``new` `int``[``100001``][``5``][``21``];`   `  ``// Recursive function to calculate maximum` `  ``// score from traversing left to right.` `  ``static` `int` `recur(``int` `i, ``int` `j, ``int` `k, ``int``[] A, ``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``][k] != -``1``)` `      ``return` `dp[i][j + ``1``][k];`   `    ``int` `ans = Integer.MIN_VALUE;`   `    ``// Calling recursive function for choosing 1` `    ``if` `((k != ``0``) || (k == ``0` `&& j == ``1``))` `      ``ans = Math.max(` `      ``ans,` `      ``recur(i + ``1``, ``1``, (j == ``1``) ? k : k - ``1``, A, N)` `      ``+ (A[i] == ``1` `? ``1` `: ``0``));`   `    ``// Calling recursive function for choosing 2` `    ``if` `((k != ``0``) || (k == ``0` `&& j == ``2``))` `      ``ans = Math.max(` `      ``ans,` `      ``recur(i + ``1``, ``2``, (j == ``2``) ? k : k - ``1``, A, N)` `      ``+ (A[i] == ``2` `? ``1` `: ``0``));`   `    ``// Calling recursive function for choosing 3` `    ``if` `((k != ``0``) || (k == ``0` `&& j == ``3``))` `      ``ans = Math.max(` `      ``ans,` `      ``recur(i + ``1``, ``3``, (j == ``3``) ? k : k - ``1``, A, N)` `      ``+ (A[i] == ``3` `? ``1` `: ``0``));`   `    ``// Save and return dp value` `    ``return` `dp[i][j + ``1``][k] = ans;` `  ``}`   `  ``// Function to calculate maximum score` `  ``// by traversing left to right` `  ``static` `int` `minCost(``int``[] A, ``int` `N, ``int` `K)` `  ``{` `    ``// Filling dp table with -1` `    ``for` `(``int``[][] dp1 : dp) {` `      ``for` `(``int``[] dp11 : dp1) {` `        ``Arrays.fill(dp11, -``1``);` `      ``}` `    ``}`   `    ``// Calling the utility function` `    ``return` `recur(``0``, -``1``, K + ``1``, A, N);` `  ``}`   `  ``public` `static` `void` `main(String[] args)` `  ``{` `    ``// Test Case 1` `    ``int``[] A = { ``1``, ``1``, ``2``, ``1``, ``3` `};` `    ``int` `K = ``1``;` `    ``int` `N = A.length;`   `    ``// Function Call` `    ``System.out.println(minCost(A, N, K));`   `    ``// Test Case 2` `    ``int``[] A1 = { ``3``, ``3``, ``1``, ``3``, ``3``, ``2``, ``2``, ``2` `};` `    ``int` `K1 = ``0``;` `    ``int` `N1 = A1.length;`   `    ``// Function Call` `    ``System.out.println(minCost(A1, N1, K1));` `  ``}` `}`   `// This code is contributed by lokesh.`

Python3

 `import` `sys`   `# dp table initialization` `dp ``=` `[[[``-``1` `for` `_ ``in` `range``(``21``)] ``for` `_ ``in` `range``(``5``)] ``for` `_ ``in` `range``(``100001``)]`   `# Recursive function to calculate maximum score from traversing left to right.` `def` `recur(i, j, k, A, 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``][k] !``=` `-``1``:` `        ``return` `dp[i][j ``+` `1``][k]`   `    ``ans ``=` `-``sys.maxsize`   `    ``# Calling recursive function for choosing 1` `    ``if` `k !``=` `0` `or` `(k ``=``=` `0` `and` `j ``=``=` `1``):` `        ``ans ``=` `max``(` `            ``ans, recur(i ``+` `1``, ``1``, k ``-` `1` `if` `j !``=` `1` `else` `k, A, N) ``+` `(A[i] ``=``=` `1``)` `        ``)`   `    ``# Calling recursive function for choosing 2` `    ``if` `k !``=` `0` `or` `(k ``=``=` `0` `and` `j ``=``=` `2``):` `        ``ans ``=` `max``(` `            ``ans, recur(i ``+` `1``, ``2``, k ``-` `1` `if` `j !``=` `2` `else` `k, A, N) ``+` `(A[i] ``=``=` `2``)` `        ``)`   `    ``# Calling recursive function for choosing 3` `    ``if` `k !``=` `0` `or` `(k ``=``=` `0` `and` `j ``=``=` `3``):` `        ``ans ``=` `max``(` `            ``ans, recur(i ``+` `1``, ``3``, k ``-` `1` `if` `j !``=` `3` `else` `k, A, N) ``+` `(A[i] ``=``=` `3``)` `        ``)`   `    ``# Save and return dp value` `    ``dp[i][j ``+` `1``][k] ``=` `ans` `    ``return` `dp[i][j ``+` `1``][k]`   `# Function to calculate maximum score by traversing left to right` `def` `minCost(A, N, K):` `    ``# Filling dp table with -1` `    ``global` `dp` `    ``dp ``=` `[[[``-``1` `for` `_ ``in` `range``(``21``)] ``for` `_ ``in` `range``(``5``)] ``for` `_ ``in` `range``(N ``+` `1``)]` `    ``# Calling the utility function` `    ``return` `recur(``0``, ``-``1``, K ``+` `1``, A, N)`   `# Driver Code` `if` `__name__ ``=``=` `'__main__'``:` `    ``# Test Case 1` `    ``A ``=` `[``1``, ``1``, ``2``, ``1``, ``3``]` `    ``K ``=` `1` `    ``N ``=` `len``(A)` `    ``# Function Call` `    ``print``(minCost(A, N, K))`   `    ``# Test Case 2` `    ``A1 ``=` `[``3``, ``3``, ``1``, ``3``, ``3``, ``2``, ``2``, ``2``]` `    ``K1 ``=` `0` `    ``N1 ``=` `len``(A1)`   `    ``# Function Call` `    ``print``(minCost(A1, N1, K1))`

C#

 `// C# code to implement the approach` `using` `System;`   `public` `class` `GFG {`   `  ``// dp table initialization` `  ``static` `int``[, , ] dp = ``new` `int``[100001, 5, 21];`   `  ``// Recursive function to calculate maximum` `  ``// score from traversing left to right.` `  ``static` `int` `recur(``int` `i, ``int` `j, ``int` `k, ``int``[] A, ``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, k] != -1) {` `      ``return` `dp[i, j + 1, k];` `    ``}`   `    ``int` `ans = ``int``.MinValue;`   `    ``// Calling recursive function for choosing 1` `    ``if` `((k != 0) || (k == 0 && j == 1)) {` `      ``ans = Math.Max(` `        ``ans,` `        ``recur(i + 1, 1, (j == 1) ? k : k - 1, A, N)` `        ``+ (A[i] == 1 ? 1 : 0));` `    ``}`   `    ``// Calling recursive function for choosing 2` `    ``if` `((k != 0) || (k == 0 && j == 2)) {` `      ``ans = Math.Max(` `        ``ans,` `        ``recur(i + 1, 2, (j == 2) ? k : k - 1, A, N)` `        ``+ (A[i] == 2 ? 1 : 0));` `    ``}`   `    ``// Calling recursive function for choosing 3` `    ``if` `((k != 0) || (k == 0 && j == 3)) {` `      ``ans = Math.Max(` `        ``ans,` `        ``recur(i + 1, 3, (j == 3) ? k : k - 1, A, N)` `        ``+ (A[i] == 3 ? 1 : 0));` `    ``}`   `    ``// Save and return dp value` `    ``return` `dp[i, j + 1, k] = ans;` `  ``}`   `  ``// Function to calculate maximum score` `  ``// by traversing left to right` `  ``static` `int` `minCost(``int``[] A, ``int` `N, ``int` `K)` `  ``{` `    ``// Filling dp table with -1` `    ``for` `(``int` `i = 0; i < dp.GetLength(0); i++) {` `      ``for` `(``int` `j = 0; j < dp.GetLength(1); j++) {` `        ``for` `(``int` `l = 0; l < dp.GetLength(2); l++) {` `          ``dp[i, j, l] = -1;` `        ``}` `      ``}` `    ``}`   `    ``// Calling the utility function` `    ``return` `recur(0, -1, K + 1, A, N);` `  ``}`   `  ``static` `public` `void` `Main()` `  ``{`   `    ``// Code` `    ``// Test Case 1` `    ``int``[] A = { 1, 1, 2, 1, 3 };` `    ``int` `K = 1;` `    ``int` `N = A.Length;`   `    ``// Function Call` `    ``Console.WriteLine(minCost(A, N, K));`   `    ``// Test Case 2` `    ``int``[] A1 = { 3, 3, 1, 3, 3, 2, 2, 2 };` `    ``int` `K1 = 0;` `    ``int` `N1 = A1.Length;`   `    ``// Function Call` `    ``Console.WriteLine(minCost(A1, N1, K1));` `  ``}` `}`   `// This code is contributed by lokeshmvs21.`

Javascript

 `// Javascript code to implement the approach`   `function` `minCost(A, N, K) {` `// dp table initialization` `    ``let dp = [];` `    ``for` `(let i = 0; i <= N; i++) {` `        ``dp[i] = [];` `        ``for` `(let j = 0; j <= 4; j++) {` `            ``dp[i][j] = [];` `            ``for` `(let k = 0; k <= 21; k++) {` `                ``dp[i][j][k] = -1;` `            ``}` `        ``}` `    ``}` `// Recursive function to calculate maximum score from traversing left to right.` `    ``function` `recur(i, j, k) {` `     ``// 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][k] !== -1) {` `            ``return` `dp[i][j + 1][k];` `        ``}`   `        ``let ans = Number.MIN_SAFE_INTEGER;` `// Calling recursive function for choosing 1` `        ``if` `((k !== 0) || (k === 0 && j === 1)) {` `            ``ans = Math.max(` `                ``ans, recur(i + 1, 1, (j === 1) ? k : k - 1) + (A[i] === 1)` `            ``);` `        ``}` `// Calling recursive function for choosing 2` `        ``if` `((k !== 0) || (k === 0 && j === 2)) {` `            ``ans = Math.max(` `                ``ans, recur(i + 1, 2, (j === 2) ? k : k - 1) + (A[i] === 2)` `            ``);` `        ``}` `// Calling recursive function for choosing 3` `        ``if` `((k !== 0) || (k === 0 && j === 3)) {` `            ``ans = Math.max(` `                ``ans, recur(i + 1, 3, (j === 3) ? k : k - 1) + (A[i] === 3)` `            ``);` `        ``}`   `        ``return` `dp[i][j + 1][k] = ans;` `    ``}`   `    ``return` `recur(0, -1, K + 1);` `}` `// Test Case 1` `let A = [1, 1, 2, 1, 3];` `let K = 1;` `let N = A.length;` `// Function Call` `console.log(minCost(A, N, K));` `// Test Case 2` `let A1 = [3, 3, 1, 3, 3, 2, 2, 2];` `let K1 = 0;` `let N1 = A1.length;` `// Function Call` `console.log(minCost(A1, N1, K1));`   `// code by ksam24000`

Output

```4
4```

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

Related Articles :

My Personal Notes arrow_drop_up