Minimum cost to make Longest Common Subsequence of length k

Given two string X, Y and an integer k. Now the task is to convert string X with minimum cost such that the Longest Common Subsequence of X and Y after conversion is of length k. The cost of conversion is calculated as XOR of old character value and new character value. Character value of ‘a’ is 0, ‘b’ is 1 and so on.

Examples:

Input : X = "abble", 
        Y = "pie",
        k = 2
Output : 25

If you changed 'a' to 'z', it will cost 0 XOR 25.

The problem can be solved by slight change in Dynamic Programming problem of Longest Increasing Subsequence. Instead of two states, we maintain three states.
Note, that if k > min(n, m) then it’s impossible to attain LCS of atleast k length, else it’s always possible.
Let dp[i][j][p] stores the minimum cost to achieve LCS of length p in x[0…i] and y[0….j].
With base step as dp[i][j][0] = 0 because we can achieve LCS of 0 legth without any cost and for i < 0 or j 0 in such case).
Else there are 3 cases:
1. Convert x[i] to y[j].
2. Skip ith character from x.
3. Skip jth character from y.

If we convert x[i] to y[j], then cost = f(x[i]) XOR f(y[j]) will be added and LCS will decrease by 1. f(x) will return the character value of x.
Note that the minimum cost to convert a character ‘a’ to any character ‘c’ is always f(a) XOR f(c) because f(a) XOR f(c) <= (f(a) XOR f(b) + f(b) XOR f(c)) for all a, b, c.
If you skip ith character from x then i will be decreased by 1, no cost will be added and LCS will remain the same.
If you skip jth character from x then j will be decreased by 1, no cost will be added and LCS will remain the same.

Therefore,

dp[i][j][k] = min(cost + dp[i - 1][j - 1][k - 1], 
                  dp[i - 1][j][k], 
                  dp[i][j - 1][k])
The minimum cost to make the length of their
LCS atleast k is dp[n - 1][m - 1][k]

.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

#include <bits/stdc++.h>
using namespace std;
const int N = 30;
  
// Return Minimum cost to make LCS of length k
int solve(char X[], char Y[], int l, int r, 
                     int k, int dp[][N][N])
{
    // If k is 0.
    if (!k)
        return 0;
  
    // If length become less than 0, return
    // big number.
    if (l < 0 | r < 0)
        return 1e9;
  
    // If state already calculated.
    if (dp[l][r][k] != -1)
        return dp[l][r][k];
  
    // Finding the cost
    int cost = (X[l] - 'a') ^ (Y[r] - 'a');
  
    // Finding minimum cost and saving the state value
    return dp[l][r][k] = min({cost +
                      solve(X, Y, l - 1, r - 1, k - 1, dp),
                             solve(X, Y, l - 1, r, k, dp), 
                             solve(X, Y, l, r - 1, k, dp)});
}
  
// Driven Program
int main()
{
    char X[] = "abble";
    char Y[] = "pie";
    int n = strlen(X);
    int m = strlen(Y);
    int k = 2;
  
    int dp[N][N][N];
    memset(dp, -1, sizeof dp);
    int ans = solve(X, Y, n - 1, m - 1, k, dp);
  
    cout << (ans == 1e9 ? -1 : ans) << endl;
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

class GFG 
{
  
    static int N = 30;
  
    // Return Minimum cost to make LCS of length k
    static int solve(char X[], char Y[], int l, int r,
                                    int k, int dp[][][])
    {
        // If k is 0.
        if (k == 0
        {
            return 0;
        }
  
        // If length become less than 0, return
        // big number.
        if (l < 0 | r < 0
        {
            return (int) 1e9;
        }
  
        // If state already calculated.
        if (dp[l][r][k] != -1
        {
            return dp[l][r][k];
        }
  
        // Finding the cost
        int cost = (X[l] - 'a') ^ (Y[r] - 'a');
  
        // Finding minimum cost and saving the state value
        return dp[l][r][k] = Math.min(Math.min(cost + 
                solve(X, Y, l - 1, r - 1, k - 1, dp),
                solve(X, Y, l - 1, r, k, dp)),
                solve(X, Y, l, r - 1, k, dp));
    }
  
    // Driver code
    public static void main(String[] args) 
    {
        char X[] = "abble".toCharArray();
        char Y[] = "pie".toCharArray();
        int n = X.length;
        int m = Y.length;
        int k = 2;
  
        int[][][] dp = new int[N][N][N];
        for (int i = 0; i < N; i++) 
        {
            for (int j = 0; j < N; j++)
            {
                for (int l = 0; l < N; l++)
                {
                    dp[i][j][l] = -1;
                }
            }
        }
        int ans = solve(X, Y, n - 1, m - 1, k, dp);
  
        System.out.println(ans == 1e9 ? -1 : ans);
    }
}
  
// This code contributed by Rajput-Ji

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to calculate Minimum cost 
# to make Longest Common Subsequence of length k
N = 30
  
# Return Minimum cost to make LCS of length k
def solve(X, Y, l, r, k, dp):
  
    # If k is 0
    if k == 0:
        return 0
  
    # If length become less than 0, 
    # return big number
    if l < 0 or r < 0:
        return 1000000000
  
    # If state already calculated
    if dp[l][r][k] != -1:
        return dp[l][r][k]
  
    # Finding cost
    cost = ((ord(X[l]) - ord('a')) ^ 
            (ord(Y[r]) - ord('a')))
  
    dp[l][r][k] = min([cost + solve(X, Y, l - 1
                                          r - 1, k - 1, dp),
                              solve(X, Y, l - 1, r, k, dp),
                              solve(X, Y, l, r - 1, k, dp)])
  
    return dp[l][r][k]
  
# Driver Code
if __name__ == "__main__":
    X = "abble"
    Y = "pie"
    n = len(X)
    m = len(Y)
    k = 2
    dp = [[[-1] * N for __ in range(N)] 
                    for ___ in range(N)]
    ans = solve(X, Y, n - 1, m - 1, k, dp)
  
    print(-1 if ans == 1000000000 else ans)
  
# This code is contributed
# by vibhu4agarwal

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find subarray with
// sum closest to 0
using System;
      
class GFG 
{
  
    static int N = 30;
  
    // Return Minimum cost to make LCS of length k
    static int solve(char []X, char []Y, int l, int r,
                                    int k, int [,,]dp)
    {
        // If k is 0.
        if (k == 0) 
        {
            return 0;
        }
  
        // If length become less than 0, return
        // big number.
        if (l < 0 | r < 0) 
        {
            return (int) 1e9;
        }
  
        // If state already calculated.
        if (dp[l,r,k] != -1) 
        {
            return dp[l,r,k];
        }
  
        // Finding the cost
        int cost = (X[l] - 'a') ^ (Y[r] - 'a');
  
        // Finding minimum cost and saving the state value
        return dp[l,r,k] = Math.Min(Math.Min(cost + 
                solve(X, Y, l - 1, r - 1, k - 1, dp),
                solve(X, Y, l - 1, r, k, dp)),
                solve(X, Y, l, r - 1, k, dp));
    }
  
    // Driver code
    public static void Main(String[] args) 
    {
        char []X = "abble".ToCharArray();
        char []Y = "pie".ToCharArray();
        int n = X.Length;
        int m = Y.Length;
        int k = 2;
  
        int[,,] dp = new int[N, N, N];
        for (int i = 0; i < N; i++) 
        {
            for (int j = 0; j < N; j++)
            {
                for (int l = 0; l < N; l++)
                {
                    dp[i,j,l] = -1;
                }
            }
        }
        int ans = solve(X, Y, n - 1, m - 1, k, dp);
  
        Console.WriteLine(ans == 1e9 ? -1 : ans);
    }
}
  
// This code is contributed by Princi Singh

chevron_right



Output:

3


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.