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][128] 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[1][s[i]] as 1.
-
Iterate over the steps [i+1, 1) using the variable len and perform the following tasks:
- Initialize a vector v[N+1] with values 0.
- Set v[0] 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++ program for the above approach #include <bits/stdc++.h> 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<vector< long long > > 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[1][s[i]] = 1;
}
vector< long long > v(N + 1, 0);
v[0] = 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 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 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
|
<script> // JavaScript code for the above approach
function accumulate(a) {
let total = 0;
for (let i in a) {
total += a[i];
}
return total;
}
// Function to find the minimum cost to
// find K unique subsequences
function minimumCost(s, k) {
let N = s.length, ans = 0;
// Stores the dp states
let dp = new Array(N + 1)
for (let i = 0; i < dp.length; i++) {
dp[i] = new Array(128).fill(0);
}
// Precompute the dp states
for (let i = 0; i < N; i++) {
// Find the sum of length
// of subsequence of length len
// ending at index S[i]
for (let len = i + 1; len > 1;
len--) {
dp[len][s[i]]
= (accumulate(dp[len - 1]));
}
// Sum of length of subsequence
// of length 1
dp[1][s[i]] = 1;
}
let v = new Array(N + 1).fill(0);
v[0] = 1;
for (let i = 1; i <= N; i++) {
v[i] += accumulate(dp[i])
}
v.reverse();
for (let i = 0; i < v.length && k > 0; i++) {
let cantake = Math.min(k, v[i]);
k -= cantake;
ans += (i * cantake);
}
return k > 0 ? -1 : ans;
}
// Driver Code
let S = "efef" ;
let K = 4;
document.write(minimumCost(S, K));
// This code is contributed by Potta Lokesh
</script> |
// 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[0] = 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 |
3
Time Complexity: O(N2)
Auxiliary Space: O(1)