Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

 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 <bits/stdc++.h>
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<Integer> pq
      = new PriorityQueue<Integer>(
      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:



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