Open In App

Maximize sum by multiplying adjacent difference of Binary String with any digit

Last Updated : 20 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary string S and a string of non-zero digits P of length N, the task is to maximize the sum using the given operations, which can be used as my times you can:

  • You can choose a substring of length 2 or 3.
  • Delete that substring after calculating the absolute difference of adjacent elements from left to right and take any single digit from the string P and multiply that with the absolute difference obtained by chosen substring.

Examples:

Input: N = 4, S = 1001, P = 6574
Output: 13
Explanation: For string S = 1001, choose a substring from index 1 to 2 as substring= 10. Absolute difference = |1 – 0| = 1 Multiply it with the digit 7 of string P = 7*1 = 7. Now chosen substring (10) is deleted from string (1001) and remaining string is = 01.
Then, choose a substring from index 1 to 2 as substring = 01. Absolute difference = |0-1| = 1, Multiply it with the 6 of string P = 6*1 = 6. Now substring is deleted and string S is empty, and total maximum sum that can obtain is 7+6 = 13.    

Input: N = 4, S = 1111, P = 1221
Output: 2
Explanation: For, string S = 1111, choose a sub-array from index 1 to 3 as sub-array = 111. Absolute difference of first left two elements of chosen substring = |1-1| = 0, Now substring is = 01.(By replacing obtained abs. difference with first two elements).
Now, absolute difference of first left two elements of current sub-array (01) = |0-1| = 1. Total absolute difference  for this substring is 1. Take digit 2 from P and multiply it with obtained absolute difference = 1*2= 2. Now delete this substring(111) from S(1111), Then remained S is = 1. 
We cannot make any operations further, Because S has single element and have not any adjacent element. Therefore, Maximum sum that can obtain is = 2.

Approach: Implement the idea below to solve the problem:

The problem can be solved by using Stack data structure and greedy approach to choose a digit from string P for multiplication. For knowing the exact algorithm to solve the problem see the Algorithm section below.

Follow the steps to solve the problem:

  • Initialize a Stack (say stk) and create a counter and sum variables.
  • Make an ArrayList lets call it digits to store digits of string P and sort it.
  • Run a loop from 1 to N and do 
    • If stk is empty or the top of stk = current_element, push the typecasted integer element in the stack.
    • Else if top of stk is not the same as current_element, pop the peek element from stk and add (1*last element of digits) into sum variable also remove used digits from the list.
  • Now it is possible that some element remained in the stack. Therefore, run a while loop till the stk has no element in it. Count the number of 1 remaining in the stk in the counter variable.
  • Modify the counter variable’s value now with (counter/3). The reason is that 3 ones can make absolute difference as 1, same as the input 2 in the example above.
  • Do the same, add (1*last element of digits ArrayList) into sum variable also remove used digits from the list, while counter is greater than 0.
  • Print the value of the sum variable.

Below is the implementation of the above approach.

C++




// C++ code to implement the approach.
 
#include <bits/stdc++.h>
using namespace std;
// Function to find the maximum possible sum
int maxSum(string S, string P, int N)
{
    // List to store digits of string P
    vector<int> digits;
 
    // Loop for initializing digits of
    // string P into list
    for (int i = 0; i < P.length(); i++) {
 
        // Initializing digits by
        // typecasting it from string
        // to integer
 
        digits.push_back(P[i] - 48);
        // digits.add(Integer.parseInt("" + P.charAt(i)));
    }
 
    // Sorting digits of list so that
    // we can get max element at last
    // index each time using greedy
    // approach
    sort(digits.begin(), digits.end());
    // digits.sort(null);
 
    int sum = 0;
    stack<int> s;
 
    // Loop for traversing on string
    for (int i = 0; i < N; i++) {
 
        // Creating current character
        // as string so that in-built
        // typecasted function can be
        // apply to below string str1
        string str1 = "";
        str1 += S[i];
 
        // Typecasted value of string
        int typecasted_int = stoi(str1);
 
        // Condition when stack is empty
        if (s.empty()) {
            s.push(typecasted_int);
        }
 
        // Condition when peek element
        // of stack is equal to current
        // typecasted element
        else if (s.top() == typecasted_int) {
            s.push(typecasted_int);
        }
 
        // Condition when peek element
        // is not equal to current
        // typecasted element
        else if (s.top() != typecasted_int) {
            sum += digits.back();
 
            // Removing used digit from list
            digits.pop_back();
            s.pop();
        }
    }
 
    int counter = 0;
 
    // While loop will run till the
    // stack is not empty
    while (!s.empty()) {
 
        // If peek element found
        // to be equal to 1
        if (s.top() == 1) {
            counter++;
        }
        s.pop();
    }
 
    // Three 111 can make abs
    // difference 1 Therefore total
    // number of 1 are divided by 3.
    counter = counter / 3;
 
    // Adding (abs diff.)*digit by
    // getting abs difference from
    // counter variable
    while (counter-- > 0) {
        sum += digits.back();
 
        // Removing used digit from list
        digits.pop_back();
    }
    return sum;
}
 
// Driver code
int main()
{
    string S = "1001";
    string P = "6574";
    int N = S.size();
 
    // Function call
    cout << (maxSum(S, P, N));
}
 
// This code is contributed by garg28harsh.


Java




// Java code to implement the approach.
 
import java.io.*;
import java.lang.*;
import java.util.*;
 
class GFG {
 
    // Function to find the maximum possible sum
    static long maxSum(String S, String P, int N)
    {
        // List to store digits of string P
        ArrayList<Integer> digits = new ArrayList<>();
 
        // Loop for initializing digits of
        // string P into list
        for (int i = 0; i < P.length(); i++) {
 
            // Initializing digits by
            // typecasting it from string
            // to integer
            digits.add(Integer.parseInt("" + P.charAt(i)));
        }
 
        // Sorting digits of list so that
        // we can get max element at last
        // index each time using greedy
        // approach
        digits.sort(null);
 
        long sum = 0;
        Stack<Integer> s = new Stack<>();
 
        // Loop for traversing on string
        for (int i = 0; i < N; i++) {
 
            // Creating current character
            // as string so that in-built
            // typecasted function can be
            // apply to below string str1
            String str1 = "" + S.charAt(i);
 
            // Typecasted value of string
            Integer typecasted_int = Integer.parseInt(str1);
 
            // Condition when stack is empty
            if (s.isEmpty()) {
                s.push(typecasted_int);
            }
 
            // Condition when peek element
            // of stack is equal to current
            // typecasted element
            else if (s.peek() == typecasted_int) {
                s.push(typecasted_int);
            }
 
            // Condition when peek element
            // is not equal to current
            // typecasted element
            else if (s.peek() != typecasted_int) {
                sum += 1
                       * (int)(digits.get(digits.size()
                                          - 1));
 
                // Removing used digit from list
                digits.remove(
                    digits.get(digits.size() - 1));
                s.pop();
            }
        }
 
        int counter = 0;
 
        // While loop will run till the
        // stack is not empty
        while (!s.isEmpty()) {
 
            // If peek element found
            // to be equal to 1
            if (s.peek() == 1) {
                counter++;
            }
            s.pop();
        }
 
        // Three 111 can make abs
        // difference 1 Therefore total
        // number of 1 are divided by 3.
        counter = counter / 3;
 
        // Adding (abs diff.)*digit by
        // getting abs difference from
        // counter variable
        while (counter-- > 0) {
            sum += 1 * digits.get(digits.size() - 1);
 
            // Removing used digit from list
            digits.remove(digits.get(digits.size() - 1));
        }
        return sum;
    }
 
    // Driver code
    public static void main(String args[])
    {
        String S = "1001";
        String P = "6574";
        int N = S.length();
 
        // Function call
        System.out.println(maxSum(S, P, N));
    }
}


Python




from typing import List
 
# Function to find the maximum possible sum
def maxSum(S, P, N):
    # List to store digits of string P
    digits = []
 
    # Loop for initializing digits of
    # string P into list
    for i in range(len(P)):
        # Initializing digits by
        # typecasting it from string to integer
        digits.append(int(P[i]))
 
    # Sorting digits of list so that
    # we can get max element at last
    # index each time using greedy
    # approach
    digits.sort()
 
    sum = 0
    s = []
    # Loop for traversing on string
    for i in range(N):
        # Creating current character
        # as string so that in-built
        # typecasted function can be
        # apply to below string str1
        typecasted_int = int(S[i])
 
        # Condition when stack is empty
        if not s:
            s.append(typecasted_int)
        # Condition when peek element
        # of stack is equal to current
        # typecasted element
        elif s[-1] == typecasted_int:
            s.append(typecasted_int)
        # Condition when peek element
        # is not equal to current
        # typecasted element
        elif s[-1] != typecasted_int:
            sum += digits[-1]
            # Removing used digit from list
            del digits[-1]
            del s[-1]
 
    counter = 0
    # While loop will run till the
    # stack is not empty
    while s:
        # If peek element found
        # to be equal to 1
        if s[-1] == 1:
            counter += 1
        del s[-1]
    # Three 111 can make abs
    # difference 1 Therefore total
    # number of 1 are divided by 3.
    counter = counter // 3
    # Adding (abs diff.)*digit by
    # getting abs difference from
    # counter variable
    while counter > 0:
        sum += digits[-1]
        # Removing used digit from list
        del digits[-1]
        counter -= 1
    return sum
 
# Driver code
if __name__ == "__main__":
    S = "1001"
    P = "6574"
    N = len(S)
 
    # Function call
    print(maxSum(S, P, N))


C#




// C# code to implement the approach.
 
using System;
using System.Collections;
using System.Collections.Generic;
 
public class GFG {
 
  // Function to find the maximum possible sum
  static long maxSum(string S, string P, int N)
  {
    // List to store digits of string P
    ArrayList digits = new ArrayList();
 
    // Loop for initializing digits of
    // string P into list
    for (int i = 0; i < P.Length; i++) {
 
      // Initializing digits by
      // typecasting it from string
      // to integer
      digits.Add(int.Parse("" + P[i]));
    }
 
    // Sorting digits of list so that
    // we can get max element at last
    // index each time using greedy
    // approach
    digits.Sort(null);
 
    long sum = 0;
    Stack s = new Stack();
 
    // Loop for traversing on string
    for (int i = 0; i < N; i++) {
 
      // Creating current character
      // as string so that in-built
      // typecasted function can be
      // apply to below string str1
      string str1 = "" + S[i];
 
      // Typecasted value of string
      int typecasted_int = int.Parse(str1);
 
      // Condition when stack is empty
      if (s.Count == 0) {
        s.Push(typecasted_int);
      }
 
      // Condition when peek element
      // of stack is equal to current
      // typecasted element
      else if ((int)s.Peek() == typecasted_int) {
        s.Push(typecasted_int);
      }
 
      // Condition when peek element
      // is not equal to current
      // typecasted element
      else if ((int)s.Peek() != typecasted_int) {
        sum += 1 * (int)(digits[digits.Count - 1]);
 
        // Removing used digit from list
        digits.Remove(digits[digits.Count - 1]);
        s.Pop();
      }
    }
 
    int counter = 0;
 
    // While loop will run till the
    // stack is not empty
    while (s.Count != 0) {
 
      // If peek element found
      // to be equal to 1
      if ((int)s.Peek() == 1) {
        counter++;
      }
      s.Pop();
    }
 
    // Three 111 can make abs
    // difference 1 Therefore total
    // number of 1 are divided by 3.
    counter = counter / 3;
 
    // Adding (abs diff.)*digit by
    // getting abs difference from
    // counter variable
    while (counter-- > 0) {
      sum += 1 * (int)digits[digits.Count - 1];
 
      // Removing used digit from list
      digits.Remove(digits[digits.Count - 1]);
    }
    return sum;
  }
 
  static public void Main()
  {
 
    // Code
    string S = "1001";
    string P = "6574";
    int N = S.Length;
 
    // Function call
    Console.WriteLine(maxSum(S, P, N));
  }
}
 
// This code is contributed by lokesh.


Javascript




// Javascript code to implement the approach.
 
// Function to find the maximum possible sum
function maxSum(S, P, N) {
    // List to store digits of string P
    let digits = [];
 
    // Loop for initializing digits of
    // string P into list
    for (let i = 0; i < P.length; i++) {
 
        // Initializing digits by
        // typecasting it from string
        // to integer
        digits.push(parseInt("" + P[i]));
    }
 
    // Sorting digits of list so that
    // we can get max element at last
    // index each time using greedy
    // approach
    digits.sort();
 
    let sum = 0;
    let s = [];
 
    // Loop for traversing on string
    for (let i = 0; i < N; i++) {
 
        // Creating current character
        // as string so that in-built
        // typecasted function can be
        // apply to below string str1
        let str1 = "" + S[i];
 
        // Typecasted value of string
        let typecasted_int = parseInt(str1);
 
        // Condition when stack is empty
        if (s.length == 0) {
            s.push(typecasted_int);
        }
 
        // Condition when peek element
        // of stack is equal to current
        // typecasted element
        else if (s[S.length - 1] == typecasted_int) {
            s.push(typecasted_int);
        }
 
        // Condition when peek element
        // is not equal to current
        // typecasted element
        else if (s[s.length - 1] != typecasted_int) {
            sum += 1
                * parseInt(digits[digits.length - 1]);
 
            // Removing used digit from list
            digits.pop();
            s.pop();
        }
    }
 
    let counter = 0;
 
    // While loop will run till the
    // stack is not empty
    while (s.length != 0) {
 
        // If peek element found
        // to be equal to 1
        if (s[S.length - 1] == 1) {
            counter++;
        }
        s.pop();
    }
 
    // Three 111 can make abs
    // difference 1 Therefore total
    // number of 1 are divided by 3.
    counter = counter / 3;
 
    // Adding (abs diff.)*digit by
    // getting abs difference from
    // counter variable
    while (counter-- > 0) {
        sum += 1 * digits[digits.length - 1];
 
        // Removing used digit from list
        digits.pop();
    }
    return sum;
}
 
// Driver code
let S = "1001";
let P = "6574";
let N = S.length;
 
// Function call
console.log(maxSum(S, P, N));
 
// This code is contributed by ksam24000


Output

13

Time Complexity: O(N * log(N)), because sorting is performed.
Auxiliary Space: O(N), as list is required to store digits. 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads