# Maximize cost of removing all occurrences of substrings “ab” and “ba”

• Difficulty Level : Hard
• Last Updated : 25 Aug, 2021

Given a string S and integers P and Q, which denotes the cost of removal of substrings “ab” and “ba” respectively from S, the task is to find the maximum cost of removing all occurrences of substrings “ab” and “ba”.

Examples:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: S = “cbbaabbaab”, P = 6, Q = 4
Output: 22
Explanation:
Removing substring “ab” from “cbbaabbaab”, the string obtained is “cbbabaab”. Cost = 6.
Removing substring “ab” from “cbbabaab”, the string obtained is “cbbaab”. Cost = 6.
Removing substring “ba” from “cbbaab”, the string obtained is “cbab”. Cost = 4.
Removing substring “ab” from “cbab“, the string obtained is “cb”. Cost = 6.
Total cost = 6 + 6 + 4 + 6 = 22

Input: S = “bbaanaybbabd”, P = 3, Q = 5
Output: 15
Explanation:
Removing substring “ba” from “bbaanaybbabd”, the string obtained is “banaybbabd”. Cost = 5.
Removing substring “ba”, the string obtained is “banaybbabd”, the string obtained is “naybbabd”. Cost = 5.
Removing substring “ba” from “naybbabd”, the string obtained is “naybbd”. Cost = 5.
Total cost = 5 + 5 + 5 = 15

Approach: The problem can be solved using Greedy technique. Follow the steps below to solve the problem:

• Traverse the string and remove one type of substring. This can be done using greedy approach as:
• If P >= Q, remove all occurrences of “ab” substring and then remove all occurrences of “ba” substring.
• Otherwise, remove all occurrences of “ba” substring and then remove all occurrences of “ab” substring.
• Stack Data Structure can be used
• Initialize our higher cost and lower cost string as “ab” or “ba” according to the value of P and Q as character arrays maxstr[] and minstr[] of size 2 and initialize maximum cost and minimum cost as maxp and minp respectively.
• Initialize variable, say cost, to store maximum cost
• Traverse the string and perform the following steps:
• If stack is not empty and top of stack and the current character forms maxstr[], then pop the stack top and add maxp to cost.
• Otherwise, add the current character to the stack.
• Traverse the remaining string.
• If stack is not empty and top of stack and the current character forms the minstr[], then pop the stack top and add minp to cost.
• Otherwise, add the current character to the stack.
• Print cost as the maximum cost.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach:``#include ``using` `namespace` `std;` `// Function to find the maximum cost of``// removing substrings "ab" and "ba" from S``int` `MaxCollection(string S, ``int` `P, ``int` `Q)``{``    ``// MaxStr is the substring char``    ``// array with larger cost``    ``char` `maxstr;``    ``string x = (P >= Q ? ``"ab"` `: ``"ba"``);``    ``strcpy``(maxstr, x.c_str());` `    ``// MinStr is the substring char``    ``// array with smaller cost;``    ``char` `minstr;``    ``x = (P >= Q ? ``"ba"` `: ``"ab"``);``    ``strcpy``(minstr, x.c_str());` `    ``// Denotes larger point``    ``int` `maxp = max(P, Q);` `    ``// Denotes smaller point``    ``int` `minp = min(P, Q);` `    ``// Stores cost scored``    ``int` `cost = 0;` `    ``// Removing all occurrences of``    ``// maxstr from the S` `    ``// Stack to keep track of characters``    ``stack<``char``> stack1;``    ``char` `s[S.length()];``    ``strcpy``(s, S.c_str());` `    ``// Traverse the string``    ``for` `(``auto` `&ch : s) {` `        ``// If the substring is maxstr` `        ``if` `(!stack1.empty()``            ``&& (stack1.top() == maxstr``                ``&& ch == maxstr)) {` `            ``// Pop from the stack``            ``stack1.pop();` `            ``// Add maxp to cost``            ``cost += maxp;``        ``}` `        ``// Push the character to the stack``        ``else` `{` `            ``stack1.push(ch);``        ``}``    ``}``    ` `    ``// Remaining string after removing maxstr``    ``string sb = ``""``;``        ` `    ``// Find remaining string``    ``while` `(stack1.size() > 0)``    ``{``        ``sb = sb + stack1.top();``        ``stack1.pop();``    ``}` `    ``// Reversing the string``    ``// retrieved from the stack``    ``reverse(sb.begin(), sb.end());` `    ``// Removing all occurences of minstr``    ``for` `(``auto` `&ch : sb) {` `        ``// If the substring is minstr``        ``if` `(!stack1.empty()``            ``&& (stack1.top() == minstr``                ``&& ch == minstr)) {` `            ``// Pop from the stack``            ``stack1.pop();` `            ``// Add minp to the cost``            ``cost += minp;``        ``}` `        ``// Otherwise``        ``else` `{``            ``stack1.push(ch);``        ``}``    ``}` `    ``// Return the maximum cost``    ``return` `cost;``}``    ` `int` `main()``{``    ``// Input String``    ``string S = ``"cbbaabbaab"``;`` ` `    ``// Costs``    ``int` `P = 6;``    ``int` `Q = 4;`` ` `    ``cout << MaxCollection(S, P, Q);` `    ``return` `0;``}` `// This code is contributed by decode2207.`

## Java

 `// Java program for the above approach:` `import` `java.util.*;` `class` `GFG {` `    ``// Function to find the maximum cost of``    ``// removing substrings "ab" and "ba" from S``    ``public` `static` `int` `MaxCollection(``        ``String S, ``int` `P, ``int` `Q)``    ``{``        ``// MaxStr is the substring char``        ``// array with larger cost``        ``char` `maxstr[]``            ``= (P >= Q ? ``"ab"` `: ``"ba"``).toCharArray();` `        ``// MinStr is the substring char``        ``// array with smaller cost;``        ``char` `minstr[]``            ``= (P >= Q ? ``"ba"` `: ``"ab"``).toCharArray();` `        ``// Denotes larger point``        ``int` `maxp = Math.max(P, Q);` `        ``// Denotes smaller point``        ``int` `minp = Math.min(P, Q);` `        ``// Stores cost scored``        ``int` `cost = ``0``;` `        ``// Removing all occurrences of``        ``// maxstr from the S` `        ``// Stack to keep track of characters``        ``Stack stack1 = ``new` `Stack<>();``        ``char``[] s = S.toCharArray();` `        ``// Traverse the string``        ``for` `(``char` `ch : s) {` `            ``// If the substring is maxstr` `            ``if` `(!stack1.isEmpty()``                ``&& (stack1.peek() == maxstr[``0``]``                    ``&& ch == maxstr[``1``])) {` `                ``// Pop from the stack``                ``stack1.pop();` `                ``// Add maxp to cost``                ``cost += maxp;``            ``}` `            ``// Push the character to the stack``            ``else` `{` `                ``stack1.push(ch);``            ``}``        ``}` `        ``// Remaining string after removing maxstr``        ``StringBuilder sb = ``new` `StringBuilder();` `        ``// Find remaining string``        ``while` `(!stack1.isEmpty())``            ``sb.append(stack1.pop());` `        ``// Reversing the string``        ``// retrieved from the stack``        ``sb = sb.reverse();``        ``String remstr = sb.toString();` `        ``// Removing all occurences of minstr``        ``for` `(``char` `ch : remstr.toCharArray()) {` `            ``// If the substring is minstr``            ``if` `(!stack1.isEmpty()``                ``&& (stack1.peek() == minstr[``0``]``                    ``&& ch == minstr[``1``])) {` `                ``// Pop from the stack``                ``stack1.pop();` `                ``// Add minp to the cost``                ``cost += minp;``            ``}` `            ``// Otherwise``            ``else` `{``                ``stack1.push(ch);``            ``}``        ``}` `        ``// Return the maximum cost``        ``return` `cost;``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{` `        ``// Input String``        ``String S = ``"cbbaabbaab"``;` `        ``// Costs``        ``int` `P = ``6``;``        ``int` `Q = ``4``;` `        ``System.out.println(MaxCollection(S, P, Q));``    ``}``}`

## Python3

 `# Python3 program for the above approach:` `# Function to find the maximum cost of``# removing substrings "ab" and "ba" from S``def` `MaxCollection(S, P, Q):``  ` `    ``# MaxStr is the substring char``    ``# array with larger cost``    ``maxstr ``=` `[i ``for` `i ``in` `(``"ab"` `if` `P >``=` `Q ``else` `"ba"``)]``    ` `    ``# MinStr is the substring char``    ``# array with smaller cost;``    ``minstr ``=` `[i ``for` `i ``in` `(``"ba"` `if` `P >``=` `Q ``else` `"ab"``)]` `    ``# Denotes larger point``    ``maxp ``=` `max``(P, Q)` `    ``# Denotes smaller point``    ``minp ``=` `min``(P, Q)` `    ``# Stores cost scored``    ``cost ``=` `0` `    ``# Removing all occurrences of``    ``# maxstr from the S` `    ``# Stack to keep track of characters``    ``stack1 ``=` `[]``    ``s ``=` `[i ``for` `i ``in` `S]``    ``# Traverse the string``    ``for` `ch ``in` `s:` `        ``# If the substring is maxstr` `        ``if` `(``len``(stack1)>``0` `and` `(stack1[``-``1``] ``=``=` `maxstr[``0``] ``and` `ch ``=``=` `maxstr[``1``])):` `            ``# Pop from the stack``            ``del` `stack1[``-``1``]` `            ``# Add maxp to cost``            ``cost ``+``=` `maxp` `        ``# Push the character to the stack``        ``else``:``            ``stack1.append(ch)` `    ``# Remaining string after removing maxstr``    ``sb ``=` `""` `    ``# Find remaining string``    ``while` `(``len``(stack1) > ``0``):``        ``sb ``+``=` `stack1[``-``1``]``        ``del` `stack1[``-``1``]` `    ``# Reversing the string``    ``# retrieved from the stack``    ``sb ``=` `sb[::``-``1``]``    ``remstr ``=` `sb` `    ``# Removing all occurences of minstr``    ``for` `ch ``in` `remstr:` `        ``# If the substring is minstr``        ``if` `(``len``(stack1) > ``0` `and` `(stack1[``-``1``] ``=``=` `minstr[``0``] ``and` `ch ``=``=` `minstr[``1``])):` `            ``#  Pop from the stack``            ``del` `stack1[``-``1``]` `            ``# Add minp to the cost``            ``cost ``+``=` `minp` `        ``# Otherwise``        ``else``:``            ``stack1.append(ch)` `    ``# Return the maximum cost``    ``return` `cost` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:` `    ``# Input String``    ``S ``=` `"cbbaabbaab"` `    ``# Costs``    ``P ``=` `6``;``    ``Q ``=` `4``;` `    ``print``(MaxCollection(S, P, Q));` `# This code is contributed by mohit kumar 29.`

## C#

 `// C# program for the above approach:``using` `System;``using` `System.Collections;``class` `GFG {``    ` `    ``// Function to find the maximum cost of``    ``// removing substrings "ab" and "ba" from S``    ``static` `int` `MaxCollection(``string` `S, ``int` `P, ``int` `Q)``    ``{``      ` `        ``// MaxStr is the substring char``        ``// array with larger cost``        ``char``[] maxstr = (P >= Q ? ``"ab"` `: ``"ba"``).ToCharArray();`` ` `        ``// MinStr is the substring char``        ``// array with smaller cost;``        ``char``[] minstr = (P >= Q ? ``"ba"` `: ``"ab"``).ToCharArray();`` ` `        ``// Denotes larger point``        ``int` `maxp = Math.Max(P, Q);`` ` `        ``// Denotes smaller point``        ``int` `minp = Math.Min(P, Q);`` ` `        ``// Stores cost scored``        ``int` `cost = 0;`` ` `        ``// Removing all occurrences of``        ``// maxstr from the S`` ` `        ``// Stack to keep track of characters``        ``Stack stack1 = ``new` `Stack();``        ``char``[] s = S.ToCharArray();`` ` `        ``// Traverse the string``        ``foreach``(``char` `ch ``in` `s) {`` ` `            ``// If the substring is maxstr`` ` `            ``if` `(stack1.Count > 0 && ((``char``)stack1.Peek() == maxstr && ch == maxstr)) {`` ` `                ``// Pop from the stack``                ``stack1.Pop();`` ` `                ``// Add maxp to cost``                ``cost += maxp;``            ``}`` ` `            ``// Push the character to the stack``            ``else` `{`` ` `                ``stack1.Push(ch);``            ``}``        ``}`` ` `        ``// Remaining string after removing maxstr``        ``string` `sb = ``""``;`` ` `        ``// Find remaining string``        ``while` `(stack1.Count > 0)``        ``{``            ``sb = sb + stack1.Peek();``            ``stack1.Pop();``        ``}`` ` `        ``// Reversing the string``        ``// retrieved from the stack``        ``char``[] chars = sb.ToCharArray();``        ``Array.Reverse(chars);``        ``string` `remstr = ``new` `string``(chars);`` ` `        ``// Removing all occurences of minstr``        ``foreach``(``char` `ch ``in` `remstr.ToCharArray()) {`` ` `            ``// If the substring is minstr``            ``if` `(stack1.Count > 0 && ((``char``)stack1.Peek() == minstr && ch == minstr)) {`` ` `                ``// Pop from the stack``                ``stack1.Pop();`` ` `                ``// Add minp to the cost``                ``cost += minp;``            ``}`` ` `            ``// Otherwise``            ``else` `{``                ``stack1.Push(ch);``            ``}``        ``}`` ` `        ``// Return the maximum cost``        ``return` `cost;``    ``}``    ` `  ``static` `void` `Main()``  ``{``    ``// Input String``    ``string` `S = ``"cbbaabbaab"``;` `    ``// Costs``    ``int` `P = 6;``    ``int` `Q = 4;` `    ``Console.Write(MaxCollection(S, P, Q));``  ``}``}` `// This code is contributed by mukesh07.`

## Javascript

 ``

Output:
`22`

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

My Personal Notes arrow_drop_up