Open In App

Find the minimum cost of partitioning the given string S into contiguous substrings

Last Updated : 12 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given a string S and an array of strings arr[]. The task is to find the minimum cost of partitioning the given string S into continuous substrings. If a substring is present in arr[] then the cost of partition would be 0, otherwise, the cost would be the length of that substring.

Examples:

Input: S = geeksforgeeks, A[] = {geek, for}
Output: 2
Explanation: The explanation is as follows:

  • Break geeksforgeeks as {geek + s + for + geek+ s}
    • 1st substring: “geek” is present in A[]. Therefore, cost is 0.
    • 2nd substring: “s” is not present in A[]. Therefore, cost is 1.
    • 3rd substring: “for” is present in A[]. Therefore, cost is 0.
    • 4th substring: “geek” is present in A[]. Therefore, cost is 0.
    • 5th substring: “s” is not present in A[]. Therefore, cost is 1.
  • Total cost = 0+1+0+0+1 = 2. Which is minimum possible.

Input: S = geeksgeeks, A[] = {ge, ek, s, eeksgeeks},
Output: 0
Explanation: S can be broken in two ways {g + eeksgeeks} and {ge + ek + s + ge + ek + s} with cost 1 and 0 respectively. 0 is minimum possible cost.

    Approach: Implement the idea below to solve the problem

    As we have choice to delete or not delete a substring. Therefore, Dynamic Programming can be used to solve this problem. The main concept of DP in the problem will be:

    • DP[i] will store the minimum cost of breaking string S till ith character.
    • Transition:
      • DP[i] = min(DP[i + 1] + 1, DP[i + e.size()]) for every ‘e’ where, e is string from array A[] and substring of string S starting from i is equal to string e.

    Step-by-step approach:

    • Declaring variable let say SizeOfS for storing size of S.
    • Declaring DP[] array of length (SizeOfS + 1).
    • Set base case as DP[SizeOfS] = 0.
    • Calculating answer for ith state by iterating from i = (SizeOfS – 1) to 0 and follow below-mentioned steps:
      • Set DP[i] with DP[i + 1] + 1
      • Iterate in array arr[] as posSubstrToDelete
        • If substring starting from ith index is equal to posSubstrToDelete, then:
          • Update DP[i] as min(DP[i], DP[i + posSubstrToDelete.size()])
    • Return DP[0].

    Below is the implementation of the above approach:

    C++
    // C++ code to implement the approach 
    #include <bits/stdc++.h> 
    using namespace std; 
    
    // Function to Minimize cost of breaking string in 
    // continuous substring 
    int minimumCost(string& S, vector<string>& A, int N) 
    { 
        // size of string 
        int szeOfS = S.size(); 
    
        // DP array initalized with infinity 
        vector<int> dp(szeOfS + 1, 1e9); 
    
        // base case 
        dp[szeOfS] = 0; 
    
        // size of string 
        for (int i = szeOfS - 1; i >= 0; i--) { 
    
            // if we dont delete i'th character 
            dp[i] = dp[i + 1] + 1; 
    
            // iterate over possible substrings that 
            // can be removed from S 
            for (auto& posSubstrToDelete : A) { 
    
                // if substring from i'th character is equal to 
                // e update the dp array by deleting this 
                // substring 
                if (i + posSubstrToDelete.size() <= szeOfS 
                    and S.substr(i, posSubstrToDelete.size()) 
                            == posSubstrToDelete) { 
                    dp[i] 
                        = min(dp[i], 
                            dp[i + posSubstrToDelete.size()]); 
                } 
            } 
        } 
    
        // Returing answer 
        return dp[0]; 
    } 
    
    // Driver Code 
    int32_t main() 
    { 
    
        // Input 
        string S1 = "geeksforgeeks"; 
        int N1 = 2; 
        vector<string> A1{ "geek", "for" }; 
    
        // Function Call 
        cout << minimumCost(S1, A1, N1) << endl; 
    
        return 0; 
    }
    
    Java
    // Java Implementation
    import java.util.ArrayList;
    import java.util.List;
    
    public class MinimumCost {
        public static int minimumCost(String S, List<String> A) {
            int szeOfS = S.length();
            int[] dp = new int[szeOfS + 1];
            for (int i = 0; i <= szeOfS; i++) {
                dp[i] = Integer.MAX_VALUE;
            }
            dp[szeOfS] = 0;
            for (int i = szeOfS - 1; i >= 0; i--) {
                dp[i] = dp[i + 1] + 1;
                for (String posSubstrToDelete : A) {
                    if (i + posSubstrToDelete.length() <= szeOfS && S.substring(i, i + posSubstrToDelete.length()).equals(posSubstrToDelete)) {
                        dp[i] = Math.min(dp[i], dp[i + posSubstrToDelete.length()]);
                    }
                }
            }
            return dp[0];
        }
    
        public static void main(String[] args) {
            String S1 = "geeksforgeeks";
            int N1 = 2;
            List<String> A1 = new ArrayList<>();
            A1.add("geek");
            A1.add("for");
            System.out.println(minimumCost(S1, A1));
        }
    }
    
    // This code is contributed by Tapesh(tapeshdu420)
    
    C#
    using System;
    using System.Collections.Generic;
    
    class Program
    {
        // Function to Minimize cost of breaking string in continuous substring
        static int MinimumCost(string S, List<string> A, int N)
        {
            // size of string
            int szeOfS = S.Length;
    
            // DP array initialized with infinity
            List<int> dp = new List<int>(new int[szeOfS + 1]);
            for (int i = 0; i < dp.Count; i++)
            {
                dp[i] = int.MaxValue;
            }
    
            // base case
            dp[szeOfS] = 0;
    
            // size of string
            for (int i = szeOfS - 1; i >= 0; i--)
            {
                // if we don't delete i'th character
                dp[i] = dp[i + 1] + 1;
    
                // iterate over possible substrings that can be removed from S
                foreach (var posSubstrToDelete in A)
                {
                    // if substring from i'th character is equal to e update the dp array by deleting this substring
                    if (i + posSubstrToDelete.Length <= szeOfS
                        && S.Substring(i, posSubstrToDelete.Length) == posSubstrToDelete)
                    {
                        dp[i] = Math.Min(dp[i], dp[i + posSubstrToDelete.Length]);
                    }
                }
            }
    
            // Returning answer
            return dp[0];
        }
    
        // Driver Code
        static void Main()
        {
            // Input
            string S1 = "geeksforgeeks";
            int N1 = 2;
            List<string> A1 = new List<string> { "geek", "for" };
    
            // Function Call
            Console.WriteLine(MinimumCost(S1, A1, N1));
    
           
        }
    }
    
    // This code is contributed by shivamgupta310570
    
    Javascript
    // Function to minimize cost of breaking string in continuous substring
    function minimumCost(S, A, N) {
        // Size of string
        const szeOfS = S.length;
    
        // DP array initialized with infinity
        const dp = new Array(szeOfS + 1).fill(1e9);
    
        // Base case
        dp[szeOfS] = 0;
    
        // Size of string
        for (let i = szeOfS - 1; i >= 0; i--) {
            // If we don't delete i'th character
            dp[i] = dp[i + 1] + 1;
    
            // Iterate over possible substrings that can be removed from S
            for (let posSubstrToDelete of A) {
                // If substring from i'th character is equal to posSubstrToDelete
                // Update the dp array by deleting this substring
                if (i + posSubstrToDelete.length <= szeOfS &&
                    S.substring(i, i + posSubstrToDelete.length) === posSubstrToDelete) {
                    dp[i] = Math.min(dp[i], dp[i + posSubstrToDelete.length]);
                }
            }
        }
    
        // Returning answer
        return dp[0];
    }
    
    // Driver Code
    // Input
    let S1 = "geeksforgeeks";
    let N1 = 2;
    let A1 = ["geek", "for"];
    
    // Function Call
    console.log(minimumCost(S1, A1, N1));
    
    // This code is contributed by shivamgupta310570
    
    Python3
    def minimum_cost(S, A, N):
        # size of string
        sze_of_S = len(S)
    
        # DP array initialized with infinity
        dp = [float('inf')] * (sze_of_S + 1)
    
        # base case
        dp[sze_of_S] = 0
    
        # size of string
        for i in range(sze_of_S - 1, -1, -1):
            # if we don't delete i'th character
            dp[i] = dp[i + 1] + 1
    
            # iterate over possible substrings that
            # can be removed from S
            for pos_substr_to_delete in A:
                # if substring from i'th character is equal to
                # e update the dp array by deleting this
                # substring
                if (
                    i + len(pos_substr_to_delete) <= sze_of_S
                    and S[i:i + len(pos_substr_to_delete)] == pos_substr_to_delete
                ):
                    dp[i] = min(dp[i], dp[i + len(pos_substr_to_delete)])
    
        # Returning answer
        return dp[0]
    
    
    # Driver Code
    if __name__ == "__main__":
        # Input
        S1 = "geeksforgeeks"
        N1 = 2
        A1 = ["geek", "for"]
    
        # Function Call
        print(minimum_cost(S1, A1, N1))
    

    Output
    2
    
    
    
    
    

    Time Complexity: O(N*M*K), where N, M, K are length of string, length of A[] and maximum size of string among all strings from A[] respectively.
    Auxiliary Space: O(N)



    Like Article
    Suggest improvement
    Share your thoughts in the comments

    Similar Reads