# Minimize total cost of picking K unique subsequences from given string

• Last Updated : 02 Mar, 2022

Given a string S of length N and a positive integer K, the task is to find the minimum total cost of picking K unique subsequence of the given string S such that the cost of picking a subsequence is the (length of S – length of that subsequence). If it is impossible to choose K unique subsequence, then print “-1“.

Examples:

Input: S = “efef”, K = 4
Output: 3
Explanation: There are 4 subsequences – “efef”, “efe”, “eef” and “fef”.
Hence, the total cost is 0 + 1 + 1 + 1 = 3.

Input: S = “aaaaa”, K = 40
Output: -1

Naive Approach: The simplest approach is to generate all possible distinct subsequences of the given string S and choose K unique subsequence of maximum possible lengths. After choosing the K subsequences, the result will be (N*K – sum of lengths of all chosen K subsequences.)

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

Efficient Approach: The above approach can also be optimized by using Dynamic Programming. The idea is to initialize the 2D DP array such that dp[i[j] signifies the sum of lengths of a unique subsequence of length i ending at character j. Now, after precomputing choose those K lengths of subsequence whose sum of lengths is maximum. Follow the steps below to solve the problem:

• Initialize the variable ans as 0.
• Initialize a 2D array dp[N+1] with value 0.
• Iterate over the range [0, N) using the variable i and perform the following tasks:
• Iterate over the steps [i+1, 1) using the variable len and perform the following tasks:
• Set dp[len][s[i]] as accumulate(dp[len – 1].begin(), dp[len – 1].end(), 0L).
• Set dp[s[i]] as 1.
• Initialize a vector v[N+1] with values 0.
• Set v as 1.
• Iterate over the range [1, N] using the variable i and perform the following tasks:
• Set v[i] as accumulate(dp[i].begin(), dp[i].end(), 0L).
• Reverse the vector v[].
• Iterate over a for loop using the variable i and perform the following tasks:
• Initialize a variable cantake as the minimum of k or v[i].
• Subtract the value cantake from k.
• Increase the value of ans by i*cantake.
• After performing the above steps, print the value of ans as the answer.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to find the minimum cost to``// find K unique subsequences``int` `minimumCost(string s, ``int` `k)``{``    ``int` `N = s.length(), ans = 0;` `    ``// Stores the dp states``    ``vector > dp(``        ``N + 1, vector<``long` `long``>(128, 0));` `    ``// Precompute the dp states``    ``for` `(``int` `i = 0; i < N; i++) {` `        ``// Find the sum of length``        ``// of subsequence of length len``        ``// ending at index S[i]``        ``for` `(``int` `len = i + 1; len > 1;``             ``len--) {``            ``dp[len][s[i]]``                ``= (accumulate(dp[len - 1].begin(),``                              ``dp[len - 1].end(), 0L));``        ``}` `        ``// Sum of length of subsequence``        ``// of length 1``        ``dp[s[i]] = 1;``    ``}``    ``vector<``long` `long``> v(N + 1, 0);` `    ``v = 1;` `    ``for` `(``int` `i = 1; i <= N; i++) {``        ``v[i] += accumulate(dp[i].begin(),``                           ``dp[i].end(), 0L);``    ``}``    ``reverse(v.begin(), v.end());``    ``for` `(``int` `i = 0; i < v.size() and k > 0; i++) {``        ``long` `long` `cantake = min<``long` `long``>(k, v[i]);``        ``k -= cantake;``        ``ans += (i * cantake);``    ``}``    ``return` `k > 0 ? -1 : ans;``}` `// Driver Code``int` `main()``{``    ``string S = ``"efef"``;``    ``int` `K = 4;``    ``cout << minimumCost(S, K);``    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.util.*;``class` `GFG{` `  ``// Function to find the minimum cost to``  ``// find K unique subsequences``  ``static` `int` `minimumCost(String s, ``int` `k)``  ``{``    ``int` `N = s.length(), ans = ``0``;` `    ``// Stores the dp states``    ``int` `[][]dp = ``new` `int``[N+``1``][``128``];` `    ``// Precompute the dp states``    ``for` `(``int` `i = ``0``; i < N; i++) {` `      ``// Find the sum of length``      ``// of subsequence of length len``      ``// ending at index S[i]``      ``for` `(``int` `len = i + ``1``; len > ``1``;``           ``len--) {``        ``dp[len][s.charAt(i)]``          ``= (accumulate(dp[len - ``1``],``0``,dp[len - ``1``].length));``      ``}` `      ``// Sum of length of subsequence``      ``// of length 1``      ``dp[``1``][s.charAt(i)] = ``1``;``    ``}``    ``int` `[]v = ``new` `int``[N + ``1``];` `    ``v[``0``] = ``1``;` `    ``for` `(``int` `i = ``1``; i <= N; i++) {``      ``v[i] += (accumulate(dp[i],``0``,dp[i].length));``    ``}``    ``v = reverse(v);``    ``for` `(``int` `i = ``0``; i < v.length && k > ``0``; i++) {``      ``long` `cantake = Math.min(k, v[i]);``      ``k -= cantake;``      ``ans += (i * cantake);``    ``}``    ``return` `k > ``0` `? -``1` `: ans;``  ``}``  ``static` `int``[] reverse(``int` `a[]) {``    ``int` `i, n = a.length, t;``    ``for` `(i = ``0``; i < n / ``2``; i++) {``      ``t = a[i];``      ``a[i] = a[n - i - ``1``];``      ``a[n - i - ``1``] = t;``    ``}``    ``return` `a;``  ``}``  ``static` `int` `accumulate(``int``[] arr, ``int` `start, ``int` `end){``    ``int` `sum=``0``;``    ``for``(``int` `i= ``0``; i < arr.length; i++)``      ``sum+=arr[i];``    ``return` `sum;``  ``}` `  ``// Driver Code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``String S = ``"efef"``;``    ``int` `K = ``4``;``    ``System.out.print(minimumCost(S, K));``  ``}``}` `// This code contributed by shikhasingrajput`

## Python3

 `# python3 code for the above approach`  `def` `accumulate(a):``    ``total ``=` `0``    ``for` `i ``in` `a:``        ``total ``+``=` `i` `    ``return` `total`  `# Function to find the minimum cost to``# find K unique subsequences``def` `minimumCost(s, k):``    ``N, ans ``=` `len``(s), ``0` `    ``# Stores the dp states``    ``dp ``=` `[[``0` `for` `_ ``in` `range``(``128``)] ``for` `_ ``in` `range``(N ``+` `1``)]` `    ``# Precompute the dp states``    ``for` `i ``in` `range``(``0``, N):` `        ``# Find the sum of length``        ``# of subsequence of length len``        ``# ending at index S[i]``        ``for` `le ``in` `range``(i ``+` `1``, ``1``, ``-``1``):` `            ``dp[le][``ord``(s[i])] ``=` `(accumulate(dp[le ``-` `1``]))` `        ``# Sum of length of subsequence``        ``# of length 1``        ``dp[``1``][``ord``(s[i])] ``=` `1` `    ``v ``=` `[``0` `for` `_ ``in` `range``(N ``+` `1``)]` `    ``v[``0``] ``=` `1` `    ``for` `i ``in` `range``(``1``, N``+``1``):``        ``v[i] ``+``=` `accumulate(dp[i])` `    ``v.reverse()` `    ``for` `i ``in` `range``(``0``, ``len``(v), ``1``):``        ``if` `k <``=` `0``:``            ``break``        ``cantake ``=` `min``(k, v[i])``        ``k ``-``=` `cantake``        ``ans ``+``=` `(i ``*` `cantake)` `    ``return` `-``1` `if` `k > ``0` `else` `ans`  `# Driver Code` `if` `__name__ ``=``=` `"__main__"``:` `    ``S ``=` `"efef"``    ``K ``=` `4``    ``print``(minimumCost(S, K))` `    ``# This code is contributed by rakeshsahni`

## Javascript

 ``

## C#

 `// C# program for the above approach``using` `System;``public` `class` `GFG``{` `  ``public` `static` `int``[] GetRow(``int``[,] matrix, ``int` `row)``  ``{``    ``var` `rowLength = matrix.GetLength(1);``    ``var` `rowVector = ``new` `int``[rowLength];` `    ``for` `(``var` `i = 0; i < rowLength; i++)``      ``rowVector[i] = matrix[row, i];` `    ``return` `rowVector;``  ``}``  ` `  ``// Function to find the minimum cost to``  ``// find K unique subsequences``  ``static` `int` `minimumCost(String s, ``int` `k) {``    ``int` `N = s.Length, ans = 0;` `    ``// Stores the dp states``    ``int``[,] dp = ``new` `int``[N + 1,128];` `    ``// Precompute the dp states``    ``for` `(``int` `i = 0; i < N; i++) {` `      ``// Find the sum of length``      ``// of subsequence of length len``      ``// ending at index S[i]``      ``for` `(``int` `len = i + 1; len > 1; len--) {``        ``int``[] row = GetRow(dp,len-1);``        ``dp[len,s[i]] = (accumulate(row, 0, row.Length));``      ``}` `      ``// Sum of length of subsequence``      ``// of length 1``      ``dp[1,s[i]] = 1;``    ``}``    ``int``[] v = ``new` `int``[N + 1];` `    ``v = 1;` `    ``for` `(``int` `i = 1; i <= N; i++) {``      ``int``[] row = GetRow(dp,i);``      ``v[i] += (accumulate(row, 0, row.Length));``    ``}``    ``v = reverse(v);``    ``for` `(``int` `i = 0; i < v.Length && k > 0; i++) {``      ``long` `cantake = Math.Min(k, v[i]);``      ``k -= (``int``)cantake;``      ``ans += (``int``)(i * cantake);``    ``}``    ``return` `k > 0 ? -1 : (``int``)ans;``  ``}` `  ``static` `int``[] reverse(``int` `[]a) {``    ``int` `i, n = a.Length, t;``    ``for` `(i = 0; i < n / 2; i++) {``      ``t = a[i];``      ``a[i] = a[n - i - 1];``      ``a[n - i - 1] = t;``    ``}``    ``return` `a;``  ``}` `  ``static` `int` `accumulate(``int``[] arr, ``int` `start, ``int` `end) {``    ``int` `sum = 0;``    ``for` `(``int` `i = 0; i < arr.Length; i++)``      ``sum += arr[i];``    ``return` `sum;``  ``}` `  ``// Driver Code``  ``public` `static` `void` `Main(String[] args) {``    ``String S = ``"efef"``;``    ``int` `K = 4;``    ``Console.Write(minimumCost(S, K));``  ``}``}` `// This code is contributed by umadevi9616`

Output
`3`

Time Complexity: O(N2)
Auxiliary Space: O(1)

My Personal Notes arrow_drop_up