Open In App

Maximize cost obtained by removal of substrings “pr” or “rp” from a given String

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Given a string str and two integers X and Y, the task is to find the maximum cost required to remove all the substrings “pr” and “rp” from the given string, where removal of substrings “rp” and “pr” costs X and Y respectively.

Examples:

Input: str = “abppprrr”, X = 5, Y = 4 
Output: 15 
Explanation: 
Following operations are performed: 
“abppprrr” -> “abpprr”, cost = 5 
“abpprr” -> “abpr”, cost = 10 
“abpr” -> “ab”, cost = 15 
Therefore, the maximized cost is 15

Input: str = “prprprrp”, X = 7, Y = 10 
Output: 37

Approach: The problem can be solved using the Greedy Approach. The idea here is to remove “pr” if X is greater than Y or remove “rp” otherwise. Follow the steps below to solve the problem.

  1. If X < Y: Swap the value of X and Y and replace the character ‘p’ to ‘r’ and vice versa in the given string.
  2. Initialize two variables countP and countR to store the count of ‘p’ and ‘r’ in the string respectively.
  3. Iterate over the array arr[] and perform the steps below: 
    • If str[i] = ‘p’: Increment the countP by 1.
    • If str[i] = ‘r’: Check the value of countP. If countP > 0, then increment the result by X and decrement the value of countP by 1. Otherwise, increment the value of countR by 1.
    • If str[i] != ‘p’ and str[i]!=’r’: Increment the result by min(countP, countR) * Y.
  4. Increment the result by min(countP, countR) * Y.
  5. Finally, after the removal of all the required substrings, print the result obtained.

C++




// C++ Program to implement
// the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to maintain the case, X>=Y
bool swapXandY(string& str, int X, int Y)
{
 
    int N = str.length();
 
    // To maintain X>=Y
    swap(X, Y);
 
    for (int i = 0; i < N; i++) {
 
        // Replace 'p' to 'r'
        if (str[i] == 'p') {
            str[i] = 'r';
        }
 
        // Replace 'r' to 'p'.
        else if (str[i] == 'r') {
            str[i] = 'p';
        }
    }
}
 
// Function to return the maximum cost
int maxCost(string str, int X, int Y)
{
    // Stores the length of the string
    int N = str.length();
 
    // To maintain X>=Y.
    if (Y > X) {
        swapXandY(str, X, Y);
    }
 
    // Stores the maximum cost
    int res = 0;
 
    // Stores the count of 'p'
    // after removal of all "pr"
    // substrings up to str[i]
    int countP = 0;
 
    // Stores the count of 'r'
    // after removal of all "pr"
    // substrings up to str[i]
    int countR = 0;
 
    // Stack to maintain the order of
    // characters after removal of
    // substrings
    for (int i = 0; i < N; i++) {
 
        if (str[i] == 'p') {
            countP++;
        }
        else if (str[i] == 'r') {
 
            // If substring "pr"
            // is removed
            if (countP > 0) {
                countP--;
 
                // Increase cost by X
                res += X;
            }
            else
                countR++;
        }
        else {
 
            // If any substring "rp"
            // left in the Stack
            res += min(countP, countR) * Y;
            countP = 0;
            countR = 0;
        }
    }
 
    // If any substring "rp"
    // left in the Stack
    res += min(countP, countR) * Y;
    return res;
}
 
// Driver Code
int main()
{
    string str = "abppprrr";
    int X = 5, Y = 4;
    cout << maxCost(str, X, Y);
}


Java




// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
 
// Function to maintain the case, X>=Y
static boolean swapXandY(char []str, int X, int Y)
{
    int N = str.length;
 
    // To maintain X>=Y
    X = X + Y;
    Y = X - Y;
    X = X - Y;
 
    for(int i = 0; i < N; i++)
    {
 
        // Replace 'p' to 'r'
        if (str[i] == 'p')
        {
            str[i] = 'r';
        }
 
        // Replace 'r' to 'p'.
        else if (str[i] == 'r')
        {
            str[i] = 'p';
        }
    }
    return true;
}
 
// Function to return the maximum cost
static int maxCost(String str, int X, int Y)
{
     
    // Stores the length of the String
    int N = str.length();
 
    // To maintain X>=Y.
    if (Y > X)
    {
        swapXandY(str.toCharArray(), X, Y);
    }
 
    // Stores the maximum cost
    int res = 0;
 
    // Stores the count of 'p'
    // after removal of all "pr"
    // subStrings up to str[i]
    int countP = 0;
 
    // Stores the count of 'r'
    // after removal of all "pr"
    // subStrings up to str[i]
    int countR = 0;
 
    // Stack to maintain the order of
    // characters after removal of
    // subStrings
    for(int i = 0; i < N; i++)
    {
        if (str.charAt(i) == 'p')
        {
            countP++;
        }
        else if (str.charAt(i) == 'r')
        {
             
            // If subString "pr"
            // is removed
            if (countP > 0)
            {
                countP--;
 
                // Increase cost by X
                res += X;
            }
            else
                countR++;
        }
        else
        {
 
            // If any subString "rp"
            // left in the Stack
            res += Math.min(countP, countR) * Y;
            countP = 0;
            countR = 0;
        }
    }
 
    // If any subString "rp"
    // left in the Stack
    res += Math.min(countP, countR) * Y;
    return res;
}
 
// Driver Code
public static void main(String[] args)
{
    String str = "abppprrr";
    int X = 5, Y = 4;
     
    System.out.print(maxCost(str, X, Y));
}
}
 
// This code is contributed by Amit Katiyar


Python3




# Python3 program to implement
# the above approach
 
# Function to maintain the case, X>=Y
def swapXandY(str, X, Y):
 
    N = len(str)
 
    # To maintain X>=Y
    X, Y = Y, X
 
    for i in range(N):
 
        # Replace 'p' to 'r'
        if(str[i] == 'p'):
            str[i] = 'r'
 
        # Replace 'r' to 'p'.
        elif(str[i] == 'r'):
            str[i] = 'p'
 
# Function to return the maximum cost
def maxCost(str, X, Y):
 
    # Stores the length of the string
    N = len(str)
 
    # To maintain X>=Y.
    if(Y > X):
        swapXandY(str, X, Y)
 
    # Stores the maximum cost
    res = 0
 
    # Stores the count of 'p'
    # after removal of all "pr"
    # substrings up to str[i]
    countP = 0
 
    # Stores the count of 'r'
    # after removal of all "pr"
    # substrings up to str[i]
    countR = 0
 
    # Stack to maintain the order of
    # characters after removal of
    # substrings
    for i in range(N):
        if(str[i] == 'p'):
            countP += 1
 
        elif(str[i] == 'r'):
 
            # If substring "pr"
            # is removed
            if(countP > 0):
                countP -= 1
 
                # Increase cost by X
                res += X
 
            else:
                countR += 1
 
        else:
             
            # If any substring "rp"
            # left in the Stack
            res += min(countP, countR) * Y
            countP = 0
            countR = 0
 
    # If any substring "rp"
    # left in the Stack
    res += min(countP, countR) * Y
 
    return res
 
# Driver Code
str = "abppprrr"
X = 5
Y = 4
 
# Function call
print(maxCost(str, X, Y))
 
# This code is contributed by Shivam Singh


C#




// C# program to implement
// the above approach
using System;
class GFG{
 
// Function to maintain the case, X>=Y
static bool swapXandY(char []str,
                      int X, int Y)
{
    int N = str.Length;
 
    // To maintain X>=Y
    X = X + Y;
    Y = X - Y;
    X = X - Y;
 
    for(int i = 0; i < N; i++)
    {
        // Replace 'p' to 'r'
        if (str[i] == 'p')
        {
            str[i] = 'r';
        }
 
        // Replace 'r' to 'p'.
        else if (str[i] == 'r')
        {
            str[i] = 'p';
        }
    }
    return true;
}
 
// Function to return the
// maximum cost
static int maxCost(String str,
                   int X, int Y)
{   
    // Stores the length of the String
    int N = str.Length;
 
    // To maintain X>=Y.
    if (Y > X)
    {
        swapXandY(str.ToCharArray(),
                  X, Y);
    }
 
    // Stores the maximum cost
    int res = 0;
 
    // Stores the count of 'p'
    // after removal of all "pr"
    // subStrings up to str[i]
    int countP = 0;
 
    // Stores the count of 'r'
    // after removal of all "pr"
    // subStrings up to str[i]
    int countR = 0;
 
    // Stack to maintain the order of
    // characters after removal of
    // subStrings
    for(int i = 0; i < N; i++)
    {
        if (str[i] == 'p')
        {
            countP++;
        }
        else if (str[i] == 'r')
        {           
            // If subString "pr"
            // is removed
            if (countP > 0)
            {
                countP--;
 
                // Increase cost by X
                res += X;
            }
            else
                countR++;
        }
        else
        {
            // If any subString "rp"
            // left in the Stack
            res += Math.Min(countP,
                            countR) * Y;
            countP = 0;
            countR = 0;
        }
    }
 
    // If any subString "rp"
    // left in the Stack
    res += Math.Min(countP,
                    countR) * Y;
    return res;
}
 
// Driver Code
public static void Main(String[] args)
{
    String str = "abppprrr";
    int X = 5, Y = 4;   
    Console.Write(maxCost(str, X, Y));
}
}
 
// This code is contributed by 29AjayKumar


Javascript




<script>
// javascript program for the
// above approach
 
// Function to maintain the case, X>=Y
function swapXandY(str, X, Y)
{
    let N = str.length;
  
    // To maintain X>=Y
    X = X + Y;
    Y = X - Y;
    X = X - Y;
  
    for(let i = 0; i < N; i++)
    {
  
        // Replace 'p' to 'r'
        if (str[i] == 'p')
        {
            str[i] = 'r';
        }
  
        // Replace 'r' to 'p'.
        else if (str[i] == 'r')
        {
            str[i] = 'p';
        }
    }
    return true;
}
  
// Function to return the maximum cost
function maxCost(str, X, Y)
{
      
    // Stores the length of the String
    let N = str.length;
  
    // To maintain X>=Y.
    if (Y > X)
    {
        swapXandY(str.split(''), X, Y);
    }
  
    // Stores the maximum cost
    let res = 0;
  
    // Stores the count of 'p'
    // after removal of all "pr"
    // subStrings up to str[i]
    let countP = 0;
  
    // Stores the count of 'r'
    // after removal of all "pr"
    // subStrings up to str[i]
    let countR = 0;
  
    // Stack to maintain the order of
    // characters after removal of
    // subStrings
    for(let i = 0; i < N; i++)
    {
        if (str[i] == 'p')
        {
            countP++;
        }
        else if (str[i] == 'r')
        {
              
            // If subString "pr"
            // is removed
            if (countP > 0)
            {
                countP--;
  
                // Increase cost by X
                res += X;
            }
            else
                countR++;
        }
        else
        {
  
            // If any subString "rp"
            // left in the Stack
            res += Math.min(countP, countR) * Y;
            countP = 0;
            countR = 0;
        }
    }
  
    // If any subString "rp"
    // left in the Stack
    res += Math.min(countP, countR) * Y;
    return res;
}
  
// Driver Code
 
    let str = "abppprrr";
    let X = 5, Y = 4;
      
    document.write(maxCost(str, X, Y));
 
// This code is contributed by target_2.
</script>


Output

15




Time Complexity:O(N), where N denotes the length of the string
Auxiliary Space:O(1)

Another Approach:

  1. First, we check either X is greater than Y or not if X > Y then removing “pr” will give us greater value and if Y > X then “rp” gives more.
  2. We should greedily remove “pr” or “rp” depending upon whether X is greater or Y is greater.
  3. We will be using a stack to keep the order same after removal of substrings.
  4. After removing all possible “pr” we will check in rest of the string if any “rp” present and we will remove them and vice versa.

C++




//{ Driver Code Starts
// Initial Template for C++
#include <bits/stdc++.h>
using namespace std;
 
// } Driver Code Ends
// User function Template for C++
class Solution {
public:
    void rp(string s, int x, int y, long long& ans,
            bool flag)
    {
        // Create an empty str to keep track of the
        // characters that have not been processed yet
        string str;
        // Iterate through each character in the string
        for (char c : s) {
            // If the character is a 'p'
            if (c == 'p') {
                // Check if there is an 'r' on top of the
                // str
                if (!str.empty() && str.back() == 'r') {
                    // If there is, remove the 'r' from the
                    // str and add y to the answer
                    ans += y;
                    str.pop_back();
                }
                else {
                    // Otherwise, add the 'p' to the str
                    str.push_back(c);
                }
            }
            else {
                // If the character is not a 'p', add it to
                // the str
                str.push_back(c);
            }
        }
        // If the flag is true, call the other function to
        // process the remaining characters
        if (flag) {
            pr(str, x, y, ans, false);
        }
    }
 
    void pr(string s, int x, int y, long long& ans,
            bool flag)
    {
        // Create an empty str to keep track of the
        // characters that have not been processed yet
        string str;
        // Iterate through each character in the string
        for (char c : s) {
            // If the character is an 'r'
            if (c == 'r') {
                // Check if there is a 'p' on top of the str
                if (!str.empty() && str.back() == 'p') {
                    // If there is, remove the 'p' from the
                    // str and add x to the answer
                    ans += x;
                    str.pop_back();
                }
                else {
                    // Otherwise, add the 'r' to the str
                    str.push_back(c);
                }
            }
            else {
                // If the character is not an 'r', add it to
                // the str
                str.push_back(c);
            }
        }
        // If the flag is true, call the other function to
        // process the remaining characters
        if (flag) {
            rp(str, x, y, ans, false);
        }
    }
 
    long long solve(int x, int y, string s)
    {
        long long ans = 0;
        // Call the appropriate function depending on the
        // value of x and y
        if (x > y) {
            pr(s, x, y, ans, true);
        }
        else {
            rp(s, x, y, ans, true);
        }
        return ans;
    }
};
 
//{ Driver Code Starts.
signed main()
{
    string s = "abppprrr";
    int x = 5, y = 4;
    Solution obj;
    long long answer = obj.solve(x, y, s);
    cout << "Maximize cost obtained by removal of substrings “pr” or “rp” : "<< answer << endl;
}
 
//Ravi Singh


Java




class Solution {
    // Function to process 'rp' substrings
    public void rp(String s, int x, int y, long[] ans,
                   boolean flag)
    {
        StringBuilder str = new StringBuilder();
 
        for (char c : s.toCharArray()) {
            if (c == 'p') {
                if (str.length() > 0
                    && str.charAt(str.length() - 1)
                           == 'r') {
                    // If 'p' follows 'r', remove 'r' and
                    // add 'y' to the answer
                    ans[0] += y;
                    str.deleteCharAt(str.length() - 1);
                }
                else {
                    // Otherwise, add 'p' to the current
                    // substring
                    str.append(c);
                }
            }
            else {
                // Add non-'p' character to the current
                // substring
                str.append(c);
            }
        }
 
        if (flag) {
            // If the flag is true, process the remaining
            // characters with 'pr' pattern
            pr(str.toString(), x, y, ans, false);
        }
    }
 
    // Function to process 'pr' substrings
    public void pr(String s, int x, int y, long[] ans,
                   boolean flag)
    {
        StringBuilder str = new StringBuilder();
 
        for (char c : s.toCharArray()) {
            if (c == 'r') {
                if (str.length() > 0
                    && str.charAt(str.length() - 1)
                           == 'p') {
                    // If 'r' follows 'p', remove 'p' and
                    // add 'x' to the answer
                    ans[0] += x;
                    str.deleteCharAt(str.length() - 1);
                }
                else {
                    // Otherwise, add 'r' to the current
                    // substring
                    str.append(c);
                }
            }
            else {
                // Add non-'r' character to the current
                // substring
                str.append(c);
            }
        }
 
        if (flag) {
            // If the flag is true, process the remaining
            // characters with 'rp' pattern
            rp(str.toString(), x, y, ans, false);
        }
    }
 
    // Main function to solve the problem
    public long solve(int x, int y, String s)
    {
        long[] ans = { 0 };
 
        if (x > y) {
            // If x is greater than y, start with 'pr'
            // pattern
            pr(s, x, y, ans, true);
        }
        else {
            // Otherwise, start with 'rp' pattern
            rp(s, x, y, ans, true);
        }
 
        return ans[0];
    }
 
    // Driver code
    public static void main(String[] args)
    {
        String s = "abppprrr";
        int x = 5, y = 4;
        Solution obj = new Solution();
        long answer = obj.solve(x, y, s);
        System.out.println(
            "Maximize cost obtained by removal of substrings “pr” or “rp” : "
            + answer);
    }
}


Python




class Solution:
    # Function to process 'rp' substrings
    def rp(self, s, x, y, ans, flag):
        str = []
 
        for c in s:
            if c == 'p':
                if str and str[-1] == 'r':
                    # If 'p' follows 'r', remove 'r' and add 'y' to the answer
                    ans[0] += y
                    str.pop()
                else:
                    # Otherwise, add 'p' to the current substring
                    str.append(c)
            else:
                # Add non-'p' character to the current substring
                str.append(c)
 
        if flag:
            # If the flag is true, process the remaining characters with 'pr' pattern
            self.pr(''.join(str), x, y, ans, False)
 
    # Function to process 'pr' substrings
    def pr(self, s, x, y, ans, flag):
        str = []
 
        for c in s:
            if c == 'r':
                if str and str[-1] == 'p':
                    # If 'r' follows 'p', remove 'p' and add 'x' to the answer
                    ans[0] += x
                    str.pop()
                else:
                    # Otherwise, add 'r' to the current substring
                    str.append(c)
            else:
                # Add non-'r' character to the current substring
                str.append(c)
 
        if flag:
            # If the flag is true, process the remaining characters with 'rp' pattern
            self.rp(''.join(str), x, y, ans, False)
 
    # Main function to solve the problem
    def solve(self, x, y, s):
        ans = [0]
 
        if x > y:
            # If x is greater than y, start with 'pr' pattern
            self.pr(s, x, y, ans, True)
        else:
            # Otherwise, start with 'rp' pattern
            self.rp(s, x, y, ans, True)
 
        return ans[0]
 
 
# Driver code
s = "abppprrr"
x = 5
y = 4
obj = Solution()
answer = obj.solve(x, y, s)
print("Maximize cost obtained by removal of substrings 'pr' or 'rp' : " + str(answer))


C#




using System;
 
class Solution {
    public void Rp(string s, int x, int y, ref long ans,
                   bool flag)
    {
        // Create an empty string to keep track of the
        // characters that have not been processed yet
        string str = "";
 
        // Iterate through each character in the string
        foreach(char c in s)
        {
            // If the character is a 'p'
            if (c == 'p') {
                // Check if there is an 'r' on top of the
                // string
                if (!string.IsNullOrEmpty(str)
                    && str[str.Length - 1] == 'r') {
                    // If there is, remove the 'r' from the
                    // string and add y to the answer
                    ans += y;
                    str = str.Remove(str.Length - 1);
                }
                else {
                    // Otherwise, add the 'p' to the string
                    str += c;
                }
            }
            else {
                // If the character is not a 'p', add it to
                // the string
                str += c;
            }
        }
 
        // If the flag is true, call the other function to
        // process the remaining characters
        if (flag) {
            Pr(str, x, y, ref ans, false);
        }
    }
 
    public void Pr(string s, int x, int y, ref long ans,
                   bool flag)
    {
        // Create an empty string to keep track of the
        // characters that have not been processed yet
        string str = "";
 
        // Iterate through each character in the string
        foreach(char c in s)
        {
            // If the character is an 'r'
            if (c == 'r') {
                // Check if there is a 'p' on top of the
                // string
                if (!string.IsNullOrEmpty(str)
                    && str[str.Length - 1] == 'p') {
                    // If there is, remove the 'p' from the
                    // string and add x to the answer
                    ans += x;
                    str = str.Remove(str.Length - 1);
                }
                else {
                    // Otherwise, add the 'r' to the string
                    str += c;
                }
            }
            else {
                // If the character is not an 'r', add it to
                // the string
                str += c;
            }
        }
 
        // If the flag is true, call the other function to
        // process the remaining characters
        if (flag) {
            Rp(str, x, y, ref ans, false);
        }
    }
 
    public long Solve(int x, int y, string s)
    {
        long ans = 0;
 
        // Call the appropriate function depending on the
        // value of x and y
        if (x > y) {
            Pr(s, x, y, ref ans, true);
        }
        else {
            Rp(s, x, y, ref ans, true);
        }
 
        return ans;
    }
 
    public static void Main()
    {
        string s = "abppprrr";
        int x = 5, y = 4;
        Solution obj = new Solution();
        long answer = obj.Solve(x, y, s);
        Console.WriteLine(
            "Maximize cost obtained by removal of substrings 'pr' or 'rp': "
            + answer);
    }
}


Javascript




class Solution {
    // Function to process 'rp' substrings
    rp(s, x, y, ans, flag) {
        const str = [];
 
        for (const c of s) {
            if (c === 'p') {
                if (str.length > 0 && str[str.length - 1] === 'r') {
                    // If 'p' follows 'r', remove 'r' and add 'y' to the answer
                    ans[0] += y;
                    str.pop();
                } else {
                    // Otherwise, add 'p' to the current substring
                    str.push(c);
                }
            } else {
                // Add non-'p' character to the current substring
                str.push(c);
            }
        }
 
        if (flag) {
            // If the flag is true, process the remaining characters with 'pr' pattern
            this.pr(str.join(''), x, y, ans, false);
        }
    }
 
    // Function to process 'pr' substrings
    pr(s, x, y, ans, flag) {
        const str = [];
 
        for (const c of s) {
            if (c === 'r') {
                if (str.length > 0 && str[str.length - 1] === 'p') {
                    // If 'r' follows 'p', remove 'p' and add 'x' to the answer
                    ans[0] += x;
                    str.pop();
                } else {
                    // Otherwise, add 'r' to the current substring
                    str.push(c);
                }
            } else {
                // Add non-'r' character to the current substring
                str.push(c);
            }
        }
 
        if (flag) {
            // If the flag is true, process the remaining characters with 'rp' pattern
            this.rp(str.join(''), x, y, ans, false);
        }
    }
 
    // Main function to solve the problem
    solve(x, y, s) {
        const ans = [0];
 
        if (x > y) {
            // If x is greater than y, start with 'pr' pattern
            this.pr(s, x, y, ans, true);
        } else {
            // Otherwise, start with 'rp' pattern
            this.rp(s, x, y, ans, true);
        }
 
        return ans[0];
    }
}
 
// Driver code
const s = "abppprrr";
const x = 5;
const y = 4;
const obj = new Solution();
const answer = obj.solve(x, y, s);
console.log("Maximize cost obtained by removal of substrings 'pr' or 'rp' : " + answer);


Output

Maximize cost obtained by removal of substrings “pr” or “rp” : 15




Time Complexity: O(N), where N denotes the length of the string
Auxiliary Space:O(N)



Last Updated : 11 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads