# Longest Common Subsequence with at most k changes allowed

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++

 `<``div` `id=``"highlighter_959432"` `class``=``"syntaxhighlighter nogutter  "``>
<``div` `class``=``"container"``><``div` `class``=``"line number1 index0 alt2"``>``// 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[0]);
int m = sizeof(arr2) / sizeof(arr2[0]);

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

## 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)

Previous
Next