# Minimum cost to delete characters from String A to remove any subsequence as String B

• Last Updated : 29 Apr, 2022

Given two strings A and B of size N and M respectively, where B is a sub-sequence of A and an array arr[] of size N, where arr[i] is the cost to delete ith character from string A. The task is to find the minimum cost to delete characters from A such that after deletion no subsequence of A is the same as B.

Examples:

Input: A = “abccd”, B = “ccd”, arr[] = {1, 2, 3, 4, 5}
Output: 3
Explanation: If we remove either ‘d’ or a single ‘c’ from A then it will not be possible to construct a sub-sequence equals to B.
Among these the cost to remove the ‘c’ at index 2 is minimum that is 3. So the answer is 3.

Input: A = “abccdabccdabccd”, B = “bccd”, arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
Output: 21
Explanation: If we remove the three ‘b’s with cost 2, 7 and 5, then A becomes “accdaccdaccd”.
Now there is no way to construct a sub-sequence = “bccd”

Approach: The naive approach to solve the problem is to use recursion and to find a common subsequence between A and B as per the following idea:

If the character of A and B matches there will be 2 options: either remove that character from A or keep that character and remove other characters.

Follow the steps mentioned below to implement the idea:

• Recursively traverse through string A using pointer i and keep a pointer j to point to B.
• In each recursive function:
• If the end of the string is reached return 0 if any character is removed (checked by a counter of deleted elements) otherwise return high positive value.
• If A[i] = B[j] there are two choices:
• Remove A[i] and add cost arr[i] to answer and recursively call for the next elements.
• Keep A[i] and move forward.
• Else keep moving forward until A[i] matches B[i].
• Return the minimum cost among the above two cases from each recursive call.
• Return the minimum cost as answer.

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

Efficient Approach: The time of the above approach can be further optimized using Dynamic Programming as per the following idea:

Use a 3D dp[][][] array to store the minimum cost until a given position in A and B and for removing at least one character. dp[i][j][] stores minimum cost to delete characters till ith index of A and jth index of B where either at least one character is deleted or not.
Hence the third dimension only has two value either 1 (at least one is deleted) or 0 (none is deleted)

Below is the implementation of the above approach.

## C++

 `// C++ program for the above approach`   `#include ` `using` `namespace` `std;`   `// Array for memoization` `int` `dp;`   `// Recursive function to calculate` `// the minimum cost using dynamic programming` `int` `minCostUtil(string& a, ``int` `n,` `                ``string& b, ``int` `m,` `                ``vector<``int``>& c, ``int` `removed)` `{`   `    ``// Base case reached the end of string` `    ``if` `(n == 0 || m == 0) {`   `        ``// Removed 0 characters` `        ``// return high (+)ve value` `        ``if` `(removed == 0)` `            ``return` `99999;` `        ``return` `0;` `    ``}`   `    ``// Return pre-calculated value` `    ``if` `(dp[n][m][removed > 0 ? 1 : 0] != -1)` `        ``return` `dp[n][m][removed > 0 ? 1 : 0];`   `    ``// If characters match return the minimum of` `    ``// 1. Removing the character from A and` `    ``// adding the cost` `    ``// 2. Moving forward to remove some other` `    ``// character and decrease the counter as` `    ``// this character will not be removed.` `    ``if` `(a[n - 1] == b[m - 1]) {` `        ``dp[n][m][removed > 0 ? 1 : 0]` `            ``= min(c[n - 1]` `                      ``+ minCostUtil(a, n - 1,` `                                    ``b, m, c, removed),` `                  ``minCostUtil(a, n - 1, b, m - 1,` `                              ``c, removed - 1));` `        ``return` `dp[n][m][removed > 0 ? 1 : 0];` `    ``}`   `    ``// If no match then move through string` `    ``// A and try removing some other` `    ``// character which matches, i.e can be` `    ``// part of the subsequence that is equal to B` `    ``else` `        ``return` `dp[n][m][removed > 0 ? 1 : 0]` `               ``= minCostUtil(a, n - 1,` `                             ``b, m, c, removed);` `}`   `// Function to calculate minimum cost` `int` `minCost(string& a, string& b,` `            ``vector<``int``>& c)` `{` `    ``memset``(dp, -1, ``sizeof``(dp));` `    ``return` `minCostUtil(a, a.size(), b,` `                       ``b.size(), c, b.size());` `}`   `// Driver code` `int` `main()` `{` `    ``string A = ``"abccdabccdabccd"``;` `    ``string B = ``"bccd"``;` `    ``vector<``int``> arr = { 1, 2, 3, 4, 5,` `                        ``6, 7, 8, 9, 10,` `                        ``11, 12, 13, 14, 15 };`   `    ``cout << minCost(A, B, arr);` `    ``return` `0;` `}`

## Java

 `// Java program for the above approach` `import` `java.util.*;`   `public` `class` `GFG {`   `  ``// Array for memoization` `  ``static` `int` `dp[][][] = ``new` `int``[``101``][``101``][``2``];`   `  ``// Recursive function to calculate` `  ``// the minimum cost using dynamic programming` `  ``static` `int` `minCostUtil(String a, ``int` `n, String b, ``int` `m,` `                         ``int``[] c, ``int` `removed)` `  ``{`   `    ``// Base case reached the end of string` `    ``if` `(n == ``0` `|| m == ``0``) {`   `      ``// Removed 0 characters` `      ``// return high (+)ve value` `      ``if` `(removed == ``0``)` `        ``return` `99999``;` `      ``return` `0``;` `    ``}`   `    ``// Return pre-calculated value` `    ``if` `(dp[n][m][removed > ``0` `? ``1` `: ``0``] != -``1``)` `      ``return` `dp[n][m][removed > ``0` `? ``1` `: ``0``];`   `    ``// If characters match return the minimum of` `    ``// 1. Removing the character from A and` `    ``// adding the cost` `    ``// 2. Moving forward to remove some other` `    ``// character and decrease the counter as` `    ``// this character will not be removed.` `    ``if` `(a.charAt(n - ``1``) == b.charAt(m - ``1``)) {` `      ``dp[n][m][removed > ``0` `? ``1` `: ``0``]` `        ``= Math.min(c[n - ``1``]` `                   ``+ minCostUtil(a, n - ``1``, b, m,` `                                 ``c, removed),` `                   ``minCostUtil(a, n - ``1``, b, m - ``1``,` `                               ``c, removed - ``1``));` `      ``return` `dp[n][m][removed > ``0` `? ``1` `: ``0``];` `    ``}`   `    ``// If no match then move through string` `    ``// A and try removing some other` `    ``// character which matches, i.e can be` `    ``// part of the subsequence that is equal to B` `    ``else` `      ``return` `dp[n][m][removed > ``0` `? ``1` `: ``0``]` `      ``= minCostUtil(a, n - ``1``, b, m, c, removed);` `  ``}`   `  ``// Function to calculate minimum cost` `  ``static` `int` `minCost(String a, String b, ``int``[] c)` `  ``{` `    ``for` `(``int` `i = ``0``; i < ``101``; i++) {` `      ``for` `(``int` `j = ``0``; j < ``101``; j++) {` `        ``for` `(``int` `k = ``0``; k < ``2``; k++) {` `          ``dp[i][j][k] = -``1``;` `        ``}` `      ``}` `    ``}` `    ``return` `minCostUtil(a, a.length(), b, b.length(), c,` `                       ``b.length());` `  ``}`   `  ``// Driver code` `  ``public` `static` `void` `main(String args[])` `  ``{` `    ``String A = ``"abccdabccdabccd"``;` `    ``String B = ``"bccd"``;` `    ``int``[] arr = { ``1``, ``2``,  ``3``,  ``4``,  ``5``,  ``6``,  ``7``, ``8``,` `                 ``9``, ``10``, ``11``, ``12``, ``13``, ``14``, ``15` `};`   `    ``System.out.print(minCost(A, B, arr));` `  ``}` `}`   `// This code is contributed by Samim Hossain Mondal.`

## Python3

 `# Python3 program for the above approach`   `# Array for memoization` `dp ``=` `[]`   `# recursive function to calculate the` `# minimum cost using dynamic programming` `def` `minCostUtil(a, n, b, m, c, removed):` `    ``global` `dp`   `    ``# Base Case - reached the end of the string` `    ``if` `n ``=``=` `0` `or` `m ``=``=` `0``:` `        ``# removed 0 characters` `        ``# return high +ve value` `        ``if` `removed ``=``=` `0``:` `            ``return` `99999` `        ``return` `0`   `    ``# return pre - calculated value` `    ``if` `dp[n][m][``int``(``bool``(removed))] !``=` `-``1``:` `        ``return` `dp[n][m][``int``(``bool``(removed))]`   `    ``# 1. Removing the character from A and` `    ``# adding the cost` `    ``# 2. Moving forward to remove some other` `    ``# character and decrease the counter as` `    ``# this character will not be removed.` `    ``if` `a[n ``-` `1``] ``=``=` `b[m ``-` `1``]:` `        ``dp[n][m][``int``(``bool``(removed))] ``=` `min``(c[n ``-` `1``] ``+` `minCostUtil(a, n ``-` `1``,` `                                                                  ``b, m, c, removed), minCostUtil(a, n ``-` `1``, b, m ``-` `1``, c, removed ``-` `1``))` `        ``return` `dp[n][m][``int``(``bool``(removed))]`   `    ``# if no match, then move through string` `    ``# A and try removing some other` `    ``# character which matches, ie, can be` `    ``# part of the subsequence that is equal to B` `    ``else``:` `        ``dp[n][m][``int``(``bool``(removed))] ``=` `minCostUtil(a, n ``-` `1``, b, m, c, removed)` `        ``return` `dp[n][m][``int``(``bool``(removed))]`   `# function to calculate minimum bed` `def` `minCost(a, b, c):` `    ``global` `dp` `    ``for` `i ``in` `range``(``101``):` `        ``dp.append([])` `        ``for` `j ``in` `range``(``101``):` `            ``dp[i].append([])` `            ``for` `k ``in` `range``(``2``):` `                ``dp[i][j].append(``-``1``)`   `    ``return` `minCostUtil(a, ``len``(a), b, ``len``(b), c, ``len``(b))`   `# Driver Code` `A ``=` `"abccdabccdabccd"` `B ``=` `"bccd"` `arr ``=` `[``1``, ``2``, ``3``, ``4``, ``5``, ``6``, ``7``, ``8``, ``9``, ``10``, ``11``, ``12``, ``13``, ``14``, ``15``]` `print``(minCost(A, B, arr))`   `# This code is contributed by phasing17`

## C#

 `// C# program for the above approach` `using` `System;`   `public` `class` `GFG{`   `  ``// Array for memoization` `  ``static` `int``[,,] dp = ``new` `int``[101, 101, 2];`   `  ``// Recursive function to calculate` `  ``// the minimum cost using dynamic programming` `  ``static` `int` `minCostUtil(``string` `a, ``int` `n, ``string` `b, ``int` `m,` `                         ``int``[] c, ``int` `removed)` `  ``{`   `    ``// Base case reached the end of string` `    ``if` `(n == 0 || m == 0) {`   `      ``// Removed 0 characters` `      ``// return high (+)ve value` `      ``if` `(removed == 0)` `        ``return` `99999;` `      ``return` `0;` `    ``}`   `    ``// Return pre-calculated value` `    ``if` `(dp[n, m, removed > 0 ? 1 : 0] != -1)` `      ``return` `dp[n, m, removed > 0 ? 1 : 0];`   `    ``// If characters match return the minimum of` `    ``// 1. Removing the character from A and` `    ``// adding the cost` `    ``// 2. Moving forward to remove some other` `    ``// character and decrease the counter as` `    ``// this character will not be removed.` `    ``if` `(a[n - 1] == b[m - 1]) {` `      ``dp[n, m, removed > 0 ? 1 : 0]` `        ``= Math.Min(c[n - 1]` `                   ``+ minCostUtil(a, n - 1, b, m,` `                                 ``c, removed),` `                   ``minCostUtil(a, n - 1, b, m - 1,` `                               ``c, removed - 1));` `      ``return` `dp[n, m, removed > 0 ? 1 : 0];` `    ``}`   `    ``// If no match then move through string` `    ``// A and try removing some other` `    ``// character which matches, i.e can be` `    ``// part of the subsequence that is equal to B` `    ``else` `      ``return` `dp[n, m, removed > 0 ? 1 : 0]` `      ``= minCostUtil(a, n - 1, b, m, c, removed);` `  ``}`   `  ``// Function to calculate minimum cost` `  ``static` `int` `minCost(``string` `a, ``string` `b, ``int``[] c)` `  ``{` `    ``for` `(``int` `i = 0; i < 101; i++) {` `      ``for` `(``int` `j = 0; j < 101; j++) {` `        ``for` `(``int` `k = 0; k < 2; k++) {` `          ``dp[i, j, k] = -1;` `        ``}` `      ``}` `    ``}` `    ``return` `minCostUtil(a, a.Length, b, b.Length, c,` `                       ``b.Length);` `  ``}`   `  ``// Driver code` `  ``static` `public` `void` `Main (){`   `    ``string` `A = ``"abccdabccdabccd"``;` `    ``string` `B = ``"bccd"``;` `    ``int``[] arr = { 1, 2,  3,  4,  5,  6,  7, 8,` `                 ``9, 10, 11, 12, 13, 14, 15 };`   `    ``Console.Write(minCost(A, B, arr));` `  ``}` `}`   `// This code is contributed by hrithikgarg03188.`

## Javascript

 `// JavaScript program for the above approach`   `// Array for memoization` `var` `dp = [];`   `// Recursive function to calculate` `// the minimum cost using dynamic programming` `function` `minCostUtil(a, n, b, m, c, removed)` `{` `    ``// Base case reached the end of string` `    ``if` `(n == 0 || m == 0) {` `        ``// Removed 0 characters` `        ``// return high (+)ve value` `        ``if` `(removed == 0)` `            ``return` `99999;` `        ``return` `0;` `    ``}`   `    ``// Return pre-calculated value` `    ``if` `(dp[n][m][Number(Boolean(removed))] != -1)` `        ``return` `dp[n][m][(removed > 0) ? 1 : 0];` `    ``// If characters match return the minimum of` `    ``// 1. Removing the character from A and` `    ``// adding the cost` `    ``// 2. Moving forward to remove some other` `    ``// character and decrease the counter as` `    ``// this character will not be removed.` `    ``if` `(a[n - 1] == b[m - 1]) {` `        ``dp[n][m][(removed > 0) ? 1 : 0] = Math.min(` `            ``c[n - 1]` `                ``+ minCostUtil(a, n - 1, b, m, c, removed),` `            ``minCostUtil(a, n - 1, b, m - 1, c,` `                        ``removed - 1));` `        ``return` `dp[n][m][(removed > 0) ? 1 : 0];` `    ``}` `    ``// If no match then move through string` `    ``// A and try removing some other` `    ``// character which matches, i.e can be` `    ``// part of the subsequence that is equal to B` `    ``else` `        ``return` `dp[n][m][(removed > 0) ? 1 : 0]` `               ``= minCostUtil(a, n - 1, b, m, c, removed);` `}` `// Function to calculate minimum cost`   `function` `minCost(a, b, c)` `{` `    ``for` `(``var` `i = 0; i < 101; i++) {` `        ``dp[i] = [];` `        ``for` `(``var` `j = 0; j < 101; j++) {` `            ``dp[i].push([]);` `            ``for` `(``var` `k = 0; k < 2; k++) {` `                ``dp[i][j].push([-1]);` `            ``}` `        ``}` `    ``}`   `    ``return` `minCostUtil(a, a.length, b, b.length, c,` `                       ``b.length);` `}`   `// Driver code` `var` `A = ``"abccdabccdabccd"``;` `var` `B = ``"bccd"``;` `var` `arr =` `    ``[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ];` `document.write(minCost(A, B, arr));`   `// This code is contributed by phasing17`

Output

`21`

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

My Personal Notes arrow_drop_up
Recommended Articles
Page :