 Open in App
Not now

# Longest Common Subsequence with at most k changes allowed

• Difficulty Level : Hard
• Last Updated : 20 Dec, 2022

Given two sequence P and Q of numbers. The task is to find Longest Common Subsequence of two sequences if we are allowed to change at most k element in first sequence to any value.

Examples:

```Input : P = { 8, 3 }
Q = { 1, 3 }
K = 1
Output : 2
If we change first element of first
sequence from 8 to 1, both sequences
become same.

Input : P = { 1, 2, 3, 4, 5 }
Q = { 5, 3, 1, 4, 2 }
K = 1
Output : 3
By changing first element of first
sequence to 5 to get the LCS ( 5, 3, 4 }.```

The idea is to use Dynamic Programming. Define a 3D matrix dp[][][], where dp[i][j][k] defines the Longest Common Subsequence for the first i numbers of first array, first j number of second array when we are allowed to change at max k number in the first array.

Therefore, recursion will look like

```If P[i] != Q[j],
dp[i][j][k] = max(dp[i - 1][j][k],
dp[i][j - 1][k],
dp[i - 1][j - 1][k - 1] + 1)
If P[i] == Q[j],
dp[i][j][k] = max(dp[i - 1][j][k],
dp[i][j - 1][k],
dp[i - 1][j - 1][k] + 1)```

Below is the implementation of this approach:

## C++

 `// CPP program to find LCS of two arrays with``// k changes allowed in first array.``#include ``using` `namespace` `std;``#define MAX 10` `// Return LCS with at most k changes allowed.``int` `lcs(``int` `dp[MAX][MAX][MAX], ``int` `arr1[], ``int` `n,``                       ``int` `arr2[], ``int` `m, ``int` `k)``{``    ``// If at most changes is less than 0.``    ``if` `(k < 0)``        ``return` `-1e7;` `    ``// If any of two array is over.``    ``if` `(n < 0 || m < 0)``        ``return` `0;` `    ``// Making a reference variable to dp[n][m][k]``    ``int``& ans = dp[n][m][k];` `    ``// If value is already calculated, return``    ``// that value.``    ``if` `(ans != -1)``        ``return` `ans;` `    ``// calculating LCS with no changes made.``    ``ans = max(lcs(dp, arr1, n - 1, arr2, m, k),``              ``lcs(dp, arr1, n, arr2, m - 1, k));` `    ``// calculating LCS when array element are same.``    ``if` `(arr1[n-1] == arr2[m-1])``        ``ans = max(ans, 1 + lcs(dp, arr1, n - 1,``                                ``arr2, m - 1, k));` `    ``// calculating LCS with changes made.``    ``ans = max(ans, 1 + lcs(dp, arr1, n - 1,``                          ``arr2, m - 1, k - 1));` `    ``return` `ans;``}` `// Driven Program``int` `main()``{``    ``int` `k = 1;``    ``int` `arr1[] = { 1, 2, 3, 4, 5 };``    ``int` `arr2[] = { 5, 3, 1, 4, 2 };``    ``int` `n = ``sizeof``(arr1) / ``sizeof``(arr1);``    ``int` `m = ``sizeof``(arr2) / ``sizeof``(arr2);` `    ``int` `dp[MAX][MAX][MAX];``    ``memset``(dp, -1, ``sizeof``(dp));` `    ``cout << lcs(dp, arr1, n, arr2, m, k) << endl;` `    ``return` `0;``}`

## Java

 `// Java program to find LCS of two arrays with``// k changes allowed in first array.``import` `java.util.*;``import` `java.io.*;` `class` `GFG``{``    ``static` `int` `MAX = ``10``;` `    ``// Return LCS with at most k changes allowed.``    ``static` `int` `lcs(``int``[][][] dp, ``int``[] arr1,   ``                   ``int` `n, ``int``[] arr2, ``int` `m, ``int` `k)``    ``{` `        ``// If at most changes is less than 0.``        ``if` `(k < ``0``)``            ``return` `-``10000000``;` `        ``// If any of two array is over.``        ``if` `(n < ``0` `|| m < ``0``)``            ``return` `0``;` `        ``// Making a reference variable to dp[n][m][k]``        ``int` `ans = dp[n][m][k];` `        ``// If value is already calculated, return``        ``// that value.``        ``if` `(ans != -``1``)``            ``return` `ans;` `        ``try``        ``{` `            ``// calculating LCS with no changes made.``            ``ans = Math.max(lcs(dp, arr1, n - ``1``, arr2, m, k),``                           ``lcs(dp, arr1, n, arr2, m - ``1``, k));` `            ``// calculating LCS when array element are same.``            ``if` `(arr1[n - ``1``] == arr2[m - ``1``])``                ``ans = Math.max(ans, ``1` `+ lcs(dp, arr1, n - ``1``,``                                                ``arr2, m - ``1``, k));` `            ``// calculating LCS with changes made.``            ``ans = Math.max(ans, ``1` `+ lcs(dp, arr1, n - ``1``,``                                            ``arr2, m - ``1``, k - ``1``));``        ``} ``catch` `(Exception e) { }``          ``// Storing the value in dp.``          ``dp[n][m][k] = ans;``        ``return` `ans;``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{``        ``int` `k = ``1``;``        ``int``[] arr1 = { ``1``, ``2``, ``3``, ``4``, ``5` `};``        ``int``[] arr2 = { ``5``, ``3``, ``1``, ``4``, ``2` `};``        ``int` `n = arr1.length;``        ``int` `m = arr2.length;` `        ``int``[][][] dp = ``new` `int``[MAX][MAX][MAX];``        ``for` `(``int` `i = ``0``; i < MAX; i++)``            ``for` `(``int` `j = ``0``; j < MAX; j++)``                ``for` `(``int` `l = ``0``; l < MAX; l++)``                    ``dp[i][j][l] = -``1``;` `        ``System.out.println(lcs(dp, arr1, n, arr2, m, k));``    ``}``}` `// This code is contributed by``// krishnat208026`

## Python3

 `# Python3 program to find LCS of two arrays``# with k changes allowed in the first array.``MAX` `=` `10` `# Return LCS with at most k changes allowed.``def` `lcs(dp, arr1, n, arr2, m, k):`` ` `    ``# If at most changes is less than 0.``    ``if` `k < ``0``:``        ``return` `-``(``10` `*``*` `7``)` `    ``# If any of two array is over.``    ``if` `n < ``0` `or` `m < ``0``:``        ``return` `0` `    ``# Making a reference variable to dp[n][m][k]``    ``ans ``=` `dp[n][m][k]` `    ``# If value is already calculated,``    ``# return that value.``    ``if` `ans !``=` `-``1``:``        ``return` `ans` `    ``# calculating LCS with no changes made.``    ``ans ``=` `max``(lcs(dp, arr1, n ``-` `1``, arr2, m, k),``            ``lcs(dp, arr1, n, arr2, m ``-` `1``, k))` `    ``# calculating LCS when array element are same.``    ``if` `arr1[n``-``1``] ``=``=` `arr2[m``-``1``]:``        ``ans ``=` `max``(ans, ``1` `+` `lcs(dp, arr1, n ``-` `1``,``                                ``arr2, m ``-` `1``, k))` `    ``# calculating LCS with changes made.``    ``ans ``=` `max``(ans, lcs(dp, arr1, n ``-` `1``,``                        ``arr2, m ``-` `1``, k ``-` `1``))``    ` `    ``dp[n][m][k]``=``ans``    ``return` `dp[n][m][k]`` ` `# Driven Program``if` `__name__ ``=``=` `"__main__"``:`` ` `    ``k ``=` `1``    ``arr1 ``=` `[``1``, ``2``, ``3``, ``4``, ``5``]``    ``arr2 ``=` `[``5``, ``3``, ``1``, ``4``, ``2``] ``    ``n ``=` `len``(arr1)``    ``m ``=` `len``(arr2)` `    ``dp ``=` `[[[``-``1` `for` `i ``in` `range``(``MAX``)] ``for` `j ``in` `range``(``MAX``)] ``for` `k ``in` `range``(``MAX``)]``    ` `    ``print``(lcs(dp, arr1, n, arr2, m, k))` `# This code is contributed by Rituraj Jain`

## C#

 `// C# program to find LCS of two arrays with``// k changes allowed in first array.``using` `System;` `class` `GFG``{``    ``static` `int` `MAX = 10;` `    ``// Return LCS with at most``    ``// k changes allowed.``    ``static` `int` `lcs(``int``[,,] dp, ``int``[] arr1,``                        ``int` `n, ``int``[] arr2,``                        ``int` `m, ``int` `k)``    ``{` `        ``// If at most changes is less than 0.``        ``if` `(k < 0)``            ``return` `-10000000;` `        ``// If any of two array is over.``        ``if` `(n < 0 || m < 0)``            ``return` `0;` `        ``// Making a reference variable``        ``// to dp[n,m,k]``        ``int` `ans = dp[n, m, k];` `        ``// If value is already calculated,``        ``// return that value.``        ``if` `(ans != -1)``            ``return` `ans;` `        ``try``        ``{` `            ``// calculating LCS with no changes made.``            ``ans = Math.Max(lcs(dp, arr1, n - 1,``                                   ``arr2, m, k),``                           ``lcs(dp, arr1, n,``                                   ``arr2, m - 1, k));` `            ``// calculating LCS when``            ``// array element are same.``            ``if` `(arr1[n - 1] == arr2[m - 1])``                ``ans = Math.Max(ans, 1 +``                           ``lcs(dp, arr1, n - 1,``                                   ``arr2, m - 1, k));` `            ``// calculating LCS with changes made.``            ``ans = Math.Max(ans, 1 +``                       ``lcs(dp, arr1, n - 1,``                               ``arr2, m - 1, k - 1));``        ``} ``catch` `(Exception e) { }``        ``return` `ans;``    ``}` `    ``// Driver Code``    ``public` `static` `void` `Main(String[] args)``    ``{``        ``int` `k = 1;``        ``int``[] arr1 = { 1, 2, 3, 4, 5 };``        ``int``[] arr2 = { 5, 3, 1, 4, 2 };``        ``int` `n = arr1.Length;``        ``int` `m = arr2.Length;` `        ``int``[,,] dp = ``new` `int``[MAX, MAX, MAX];``        ``for` `(``int` `i = 0; i < MAX; i++)``            ``for` `(``int` `j = 0; j < MAX; j++)``                ``for` `(``int` `l = 0; l < MAX; l++)``                    ``dp[i, j, l] = -1;` `        ``Console.WriteLine(lcs(dp, arr1, n,``                                  ``arr2, m, k));``    ``}``}` `// This code is contributed by PrinciRaj1992`

## Javascript

 ``

Output

```4
```

Time Complexity: O(N*M*K).
Auxiliary Space: O(MAX3)

This article is contributed by Anuj Chauhan. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.