Open in App
Not now

Find the maximum sum on the basis of the given Binary String

• Last Updated : 16 Feb, 2023

Given a binary string str and an array of positive integers profit[]. The task is to find the maximum possible sum if we are allowed to use only the elements whose corresponding index has a ‘1’ in the binary string and any “01” substring can be changed to a “10” substring.

Examples:

Input: str = “01110”, profit[] = {10, 5, 8, 9, 6}
Output: 27
Explanation: Initially, the profit is 5 + 8 + 9 = 22. After one operation, the string can be made “10110” which will give the sum as 10 + 8 + 9 = 27.

Input: str = “011011”, profit[] = {20, 10, 9, 30, 20, 9}
Output: 80

Approach: This can be solved using the following idea.

The problem can be solved using a greedy approach. We can set any ‘0’ bit if there is at least one ‘1’ after it in the string. Consider, there are X 1s in the string. So the optimal idea is to select top X elements from the array such that they all lie before the last ‘1’ of the binary string.

We can implement this idea using a max heap (priority queue).

Follow the steps mentioned below to solve the problem:

• Initialize a priority queue (say pq) which will implement a max heap.
• Iterate over the binary string and for each index:
• Enter the corresponding value of the array in the priority queue.
• If the character in the binary string is ‘1’ pop the topmost element and add it to the answer.
• Return the answer after the iteration is over.

Below is the implementation of the above approach:

C++

 `// C++ code for the above approach` `#include ` `using` `namespace` `std;`   `// Function to find the maximum profit` `int` `findmax_profit(``int` `profit[], string str, ``int` `n)` `{` `    ``// Initialize a priority queue to implement the max heap` `    ``priority_queue<``int``> pq;` `    ``int` `res = 0;`   `    ``// Loop to find the maximum possible sum` `    ``for` `(``int` `i = 0; i < n; i++) {`   `        ``// Insert the array value in priority queue` `        ``pq.push(profit[i]);`   `        ``// If the string value is '1'` `        ``// pop the highest possible value` `        ``// from priority queue` `        ``if` `(str[i] == ``'1'``) {` `            ``res += pq.top();` `            ``pq.pop();` `        ``}` `    ``}`   `    ``// Return the res` `    ``return` `res;` `}`   `// Driver code` `int` `main()` `{` `    ``// Test case 1` `    ``int` `profit[] = { 12, 10, 5, 8, 9, 6 };` `    ``string str = ``"001110"``;` `    ``int` `N = ``sizeof``(profit) / ``sizeof``(profit[0]);` `    ``cout << findmax_profit(profit, str, N) << endl;`   `    ``// Test case 2` `    ``int` `profit1[] = { 10, 5, 8, 9, 6 };` `    ``string str1 = ``"01110"``;` `    ``N = ``sizeof``(profit1) / ``sizeof``(profit1[0]);` `    ``cout << findmax_profit(profit1, str1, N) << endl;`   `    ``// Test case 3` `    ``int` `profit2[] = { 20, 10, 9, 30, 20, 9 };` `    ``string str2 = ``"011011"``;` `    ``N = ``sizeof``(profit2) / ``sizeof``(profit2[0]);` `    ``cout << findmax_profit(profit2, str2, N);`   `    ``return` `0;` `}`

Java

 `// Java code for the above approach`   `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG {`   `  ``// Function to find the maximum profit` `  ``static` `int` `findmax_profit(``int``[] profit, String str,` `                            ``int` `n)` `  ``{` `    ``// Initialize a priority queue to implement the max` `    ``// heap` `    ``PriorityQueue pq` `      ``= ``new` `PriorityQueue(` `      ``Collections.reverseOrder());` `    ``int` `res = ``0``;`   `    ``// Loop to find the maximum possible sum` `    ``for` `(``int` `i = ``0``; i < n; i++) {` `      ``// Insert the array value in priority queue` `      ``pq.add(profit[i]);`   `      ``// If the string value is '1'` `      ``// pop the highest possible value` `      ``// from priority queue` `      ``if` `(str.charAt(i) == ``'1'``) {` `        ``res += pq.peek();` `        ``pq.poll();` `      ``}` `    ``}`   `    ``// Return the res` `    ``return` `res;` `  ``}`   `  ``public` `static` `void` `main(String[] args)` `  ``{` `    ``// Test case 1` `    ``int``[] profit = { ``12``, ``10``, ``5``, ``8``, ``9``, ``6` `};` `    ``String str = ``"001110"``;` `    ``int` `N = profit.length;` `    ``System.out.println(findmax_profit(profit, str, N));`   `    ``// Test case 2` `    ``int``[] profit1 = { ``10``, ``5``, ``8``, ``9``, ``6` `};` `    ``String str1 = ``"01110"``;` `    ``N = profit1.length;` `    ``System.out.println(` `      ``findmax_profit(profit1, str1, N));`   `    ``// Test case 3` `    ``int``[] profit2 = { ``20``, ``10``, ``9``, ``30``, ``20``, ``9` `};` `    ``String str2 = ``"011011"``;` `    ``N = profit2.length;` `    ``System.out.println(` `      ``findmax_profit(profit2, str2, N));` `  ``}` `}`

Python3

 `# Python code for the above approach` `import` `bisect`   `# Function to find the maximum profit` `def` `findmax_profit(profit,``str``,n):` `    ``# Initialize a priority queue to implement the max heap` `    ``pq``=``[]` `    ``res``=``0` `    `  `    ``# Loop to find the maximum possible sum` `    ``for` `i ``in` `range``(n):` `        ``# Insert the array value in priority queue` `        ``bisect.insort(pq,profit[i])` `        `  `        ``# If the string value is '1'` `        ``# pop the highest possible value` `        ``# from priority queue` `        ``if``(``str``[i]``=``=``'1'``):` `            ``res``+``=``pq[``-``1``]` `            ``pq.pop(``-``1``)` `    `  `    ``# Return the res` `    ``return` `res` `    `  `# Driver code`   `# Test case 1` `profit``=``[``12``,``10``,``5``,``8``,``9``,``6``]` `str``=``"001110"` `N``=``len``(profit)` `print``(findmax_profit(profit,``str``,N))`   `# Test case 2` `profit1``=``[``10``,``5``,``8``,``9``,``6``]` `str1``=``"01110"` `N``=``len``(profit1)` `print``(findmax_profit(profit1,str1,N))`   `# Test case 3` `profit2``=``[``20``,``10``,``9``,``30``,``20``,``9``]` `str2``=``"011011"` `N``=``len``(profit2)` `print``(findmax_profit(profit2,str2,N))`   `# This code is contributed by Pushpesh Raj.`

C#

 `// C# code for the above approach` `using` `System;` `using` `System.Collections.Generic;`   `namespace` `MaxProfit` `{` `    ``class` `Program` `    ``{` `        ``// Function to find the maximum profit` `        ``static` `int` `FindMaxProfit(``int``[] profit, ``string` `str)` `        ``{` `            ``// Initialize a priority queue to implement the max heap` `            ``int` `n = profit.Length;` `            ``int` `res = 0;` `            ``var` `pq = ``new` `SortedSet<``int``>(Comparer<``int``>.Create((a, b) => b.CompareTo(a)));`   `            ``for` `(``int` `i = 0; i < n; i++)` `            ``{` `               ``// Insert the array value in priority queue` `                ``pq.Add(profit[i]);` `                `  `                 ``// If the string value is '1'` `                ``// pop the highest possible value` `                ``// from priority queue` `              `  `                ``if` `(str[i] == ``'1'``)` `                ``{` `                    ``res += pq.Min;` `                    ``pq.Remove(pq.Min);` `                ``}` `            ``}` `            `  `            ``// Return the res` `            ``return` `res;` `        ``}` `        `  `        ``// Driver code` `        ``static` `void` `Main(``string``[] args)` `        ``{` `            ``// Test case 1` `            ``int``[] profit = { 12, 10, 5, 8, 9, 6 };` `            ``string` `str = ``"001110"``;` `            ``Console.WriteLine(FindMaxProfit(profit, str));` `            `  `            ``// Test case 2` `            ``int``[] profit1 = { 10, 5, 8, 9, 6 };` `            ``string` `str1 = ``"01110"``;` `            ``Console.WriteLine(FindMaxProfit(profit1, str1));` `            `  `            ``// Test case 3` `            ``int``[] profit2 = { 20, 10, 9, 30, 20, 9 };` `            ``string` `str2 = ``"011011"``;` `            ``Console.WriteLine(FindMaxProfit(profit2, str2));` `        ``}` `    ``}` `}` `// This code is contributed by Rutik Bhosale..`

Javascript

 `// JavaScript code for the above approach`   `class MaxHeap {` `    ``constructor() {` `        ``this``.values = [];` `    ``}`   `    ``// index of the parent node` `    ``parent(index) {` `        ``return` `Math.floor((index - 1) / 2);` `    ``}`   `    ``// index of the left child node` `    ``leftChild(index) {` `        ``return` `(index * 2) + 1;` `    ``}`   `    ``// index of the right child node` `    ``rightChild(index) {` `        ``return` `(index * 2) + 2;` `    ``}`   `    ``// returns true if index is of a node that has no children` `    ``isLeaf(index) {` `        ``return` `(` `            ``index >= Math.floor(``this``.values.length / 2) && index <= ``this``.values.length - 1` `        ``)` `    ``}`   `    ``// swap using ES6 destructuring` `    ``swap(index1, index2) {` `        ``[``this``.values[index1], ``this``.values[index2]] = [``this``.values[index2], ``this``.values[index1]];` `    ``}`     `    ``heapifyDown(index) {`   `        ``// if the node at index has children` `        ``if` `(!``this``.isLeaf(index)) {`   `            ``// get indices of children` `            ``let leftChildIndex = ``this``.leftChild(index),` `                ``rightChildIndex = ``this``.rightChild(index),`   `                ``// start out largest index at parent index` `                ``largestIndex = index;`   `            ``// if the left child > parent` `            ``if` `(``this``.values[leftChildIndex] > ``this``.values[largestIndex]) {` `                ``// reassign largest index to left child index` `                ``largestIndex = leftChildIndex;` `            ``}`   `            ``// if the right child > element at largest index (either parent or left child)` `            ``if` `(``this``.values[rightChildIndex] >= ``this``.values[largestIndex]) {` `                ``// reassign largest index to right child index` `                ``largestIndex = rightChildIndex;` `            ``}`   `            ``// if the largest index is not the parent index` `            ``if` `(largestIndex !== index) {` `                ``// swap` `                ``this``.swap(index, largestIndex);` `                ``// recursively move down the heap` `                ``this``.heapifyDown(largestIndex);` `            ``}` `        ``}` `    ``}`   `    ``heapifyUp(index) {` `        ``let currentIndex = index,` `            ``parentIndex = ``this``.parent(currentIndex);`   `        ``// while we haven't reached the root node and the current element is greater than its parent node` `        ``while` `(currentIndex > 0 && ``this``.values[currentIndex] > ``this``.values[parentIndex]) {` `            ``// swap` `            ``this``.swap(currentIndex, parentIndex);` `            ``// move up the binary heap` `            ``currentIndex = parentIndex;` `            ``parentIndex = ``this``.parent(parentIndex);` `        ``}` `    ``}`   `    ``add(element) {` `        ``// add element to the end of the heap` `        ``this``.values.push(element);` `        ``// move element up until it's in the correct position` `        ``this``.heapifyUp(``this``.values.length - 1);` `    ``}`   `    ``// returns value of max without removing` `    ``peek() {` `        ``return` `this``.values[0];` `    ``}`   `    ``// removes and returns max element` `    ``extractMax() {` `        ``if` `(``this``.values.length < 1) ``return` `'heap is empty'``;`   `        ``// get max and last element` `        ``const max = ``this``.values[0];` `        ``const end = ``this``.values.pop();` `        ``// reassign first element to the last element` `        ``this``.values[0] = end;` `        ``// heapify down until element is back in its correct position` `        ``this``.heapifyDown(0);`   `        ``// return the max` `        ``return` `max;` `    ``}`   `    ``buildHeap(array) {` `        ``this``.values = array;` `        ``// since leaves start at floor(nodes / 2) index, we work from the leaves up the heap` `        ``for``(let i = Math.floor(``this``.values.length / 2); i >= 0; i--){` `            ``this``.heapifyDown(i);` `        ``}` `    ``}`   `    ``/*print() {` `        ``let i = 0;` `        ``while (!this.isLeaf(i)) {` `            ``console.log("PARENT:", this.values[i]);` `            ``console.log("LEFT CHILD:", this.values[this.leftChild(i)]);` `            ``console.log("RIGHT CHILD:", this.values[this.rightChild(i)]);` `            ``i++;` `        ``}      ` `    ``}*/` `}`   `// Function to find the maximum profit` `function` `findmax_profit(profit, str, n)` `{` `    ``// Initialize a priority queue to implement the max heap` `    ``let pq = ``new` `MaxHeap();` `    ``let res = 0;`   `    ``// Loop to find the maximum possible sum` `    ``for` `(let i = 0; i < n; i++) {`   `        ``// Insert the array value in priority queue` `        ``pq.add(profit[i]);`   `        ``// If the string value is '1'` `        ``// pop the highest possible value` `        ``// from priority queue` `        ``if` `(str[i] == ``'1'``) {` `            ``res += pq.peek();` `            ``pq.extractMax();` `        ``}` `    ``}`   `    ``// Return the res` `    ``return` `res;` `}`   `// Driver code` `    ``// Test case 1` `    ``let profit = [ 12, 10, 5, 8, 9, 6 ];` `    ``let str = ``"001110"``;` `    ``let N = profit.length;` `    ``console.log(findmax_profit(profit, str, N));`   `    ``// Test case 2` `    ``let profit1 = [ 10, 5, 8, 9, 6 ];` `    ``let str1 = ``"01110"``;` `    ``N = profit.length;` `    ``console.log(findmax_profit(profit1, str1, N));`   `    ``// Test case 3` `    ``let profit2 = [ 20, 10, 9, 30, 20, 9 ];` `    ``let str2 = ``"011011"``;` `    ``N = profit.length;` `    ``console.log(findmax_profit(profit2, str2, N));`   `// This code is contributed by poojaagarwal2.`

Output

```31
27
80```

Time Complexity: O(N * logN) where N is the length of the array.
Auxiliary Space: O(N), since we are using a priority queue data structure and in the worst case all elements of the array will be inserted in the priority queue thus taking up space equal to the size of the array

Related Articles:

My Personal Notes arrow_drop_up
Related Articles