Open In App

Maximum possible balanced binary substring splits with at most cost K

Last Updated : 24 Nov, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary array arr[] and a value array val[]. The task is to find the maximum possible splits of the binary array that can be done such that each segment contains an equal number of 0s and 1s using at most k coins. Each split costs (val[i] – val[j])2, where i and j are the adjacent indices of the split segment.

Examples:

Input: arr[] = {0, 1, 0, 0, 1, 1}, val[] = {2, 5, 1, 3, 6, 10}, k = 20
Output: 1
Explanation: Splits can be done in the following way: 0 1 | 0 0 1 1 and cost = (5 –  1)2 = 16 ≤ 20.

Input: arr[] = {1, 0, 0, 1, 0, 1, 1, 0}, val[] = {9, 7, 5, 2, 4, 12, 3, 1], k = 10
Output: 2
Explanation: Splits can be done in the following way: 1 0 | 0 1 | 0 1 1 0

 

Approach: The task can be solved using dynamic programming (Top-down approach). 
Follow the below steps:

  1. Initialize a 2d matrix say dp of dimensions K * N.
  2. For every index, there are two choices, whether to make a cut at that index or to not make a cut at that index, provided that the number of zeroes and ones are equal.
  3. Memoize the values, to be used again
  4. Maximize the value of count_splits, to get the resultant maximum cuts.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
int dp[1001][1001];
 
// Function to find maximum possible splits
// in atmost k coins such that each
// segment contains equal number of 0 and 1
int maximumSplits(int arr[], int val[],
                  int k, int N)
{
    // Base Case
    if (k < 0) {
        return INT_MIN;
    }
 
    // If already have a stored value
    // return it
    if (dp[k][N] != -1) {
        return dp[k][N];
    }
 
    // Count for zeros and ones
    int zero = 0, one = 0;
 
    // Count for number of splits
    int count_split = 0;
    int i;
 
    // Iterate over the array and
    // search for zeros and ones
    for (i = N - 1; i > 0; i--) {
        arr[i] == 0 ? zero++ : one++;
 
        // If count of zeros is equal to
        // count of ones
        if (zero == one) {
            // Store the maximum possible one
            count_split = max(
                count_split,
                1
                    + maximumSplits(
                          arr, val,
                          k - pow(val[i]
                                      - val[i - 1],
                                  2),
                          i));
        }
    }
 
    // If index is at 0, find if
    // it is zero or one and
    // increment the count
    if (i == 0) {
        arr[0] == 0 ? zero++ : one++;
 
        // If count of zero is not equal to
        // count of one, re-initialize
        // count_split with 0
        if (zero != one) {
            count_split = 0;
        }
    }
 
    // Store the returned value in dp[]
    return dp[k][N] = count_split;
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 0, 0, 1, 0, 1, 1, 0 };
    int val[] = { 9, 7, 5, 2, 4, 12, 3, 1 };
    int k = 10;
 
    int N = sizeof(arr) / sizeof(arr[0]);
    memset(dp, -1, sizeof(dp));
 
    cout << maximumSplits(arr, val, k, N);
 
    return 0;
}


Java




// Java program for the above approach
public class GFG
{
 
static int[][] dp = new int[1001][1001];
 
// Function to find maximum possible splits
// in atmost k coins such that each
// segment contains equal number of 0 and 1
static int maximumSplits(int[] arr, int[] val,
                  int k, int N)
{
   
    // Base Case
    if (k < 0) {
        return Integer.MIN_VALUE;
    }
 
    // If already have a stored value
    // return it
    if (dp[k][N] != -1) {
        return dp[k][N];
    }
 
    // Count for zeros and ones
    int zero = 0, one = 0;
 
    // Count for number of splits
    int count_split = 0;
    int i;
 
    // Iterate over the array and
    // search for zeros and ones
    for (i = N - 1; i > 0; i--) {
        if(arr[i] == 0)
            zero++;
        else
            one++;
 
        // If count of zeros is equal to
        // count of ones
        if (zero == one) {
            // Store the maximum possible one
            count_split = Math.max(
                count_split,
                1
                    + maximumSplits(
                          arr, val,
                          k - (int)Math.pow(val[i]
                                      - val[i - 1],
                                  2),
                          i));
        }
    }
 
    // If index is at 0, find if
    // it is zero or one and
    // increment the count
    if (i == 0) {
        if(arr[0] == 0)
            zero++;
        else
            one++;
 
        // If count of zero is not equal to
        // count of one, re-initialize
        // count_split with 0
        if (zero != one) {
            count_split = 0;
        }
    }
 
    // Store the returned value in dp[]
    return dp[k][N] = count_split;
}
  
 
// Driver code
public static void main(String[] args)
{
    int[] arr = { 1, 0, 0, 1, 0, 1, 1, 0 };
    int[] val = { 9, 7, 5, 2, 4, 12, 3, 1 };
    int k = 10;
 
    int N = arr.length;
    int i, j;
    for(i=0;i<1001;i++)
    {
        for(j=0;j<1001;j++)
        {
            dp[i][j] = -1;
        }
    }
 
    System.out.println(maximumSplits(arr, val, k, N));
}
}
 
// This code is contributed by AnkThon


Python3




# Python Program to implement
# the above approach
dp = [0] * 1001
for i in range(len(dp)):
    dp[i] = [-1] * 1001
 
# Function to find maximum possible splits
# in atmost k coins such that each
# segment contains equal number of 0 and 1
def maximumSplits(arr, val, k, N):
 
    # Base Case
    if (k < 0):
        return 10 ** (-9)
     
    # If already have a stored value
    # return it
    if (dp[k][N] != -1) :
        return dp[k][N]
     
    # Count for zeros and ones
    zero = 0
    one = 0
 
    # Count for number of splits
    count_split = 0
 
    # Iterate over the array and
    # search for zeros and ones
    for i in range(N - 1, 0, -1):
        if (arr[i] == 0):
            zero += 1
        else: one += 1
 
        # If count of zeros is equal to
        # count of ones
        if (zero == one):
 
            # Store the maximum possible one
            count_split = max(
                count_split, 1
                + maximumSplits(
                    arr, val,
                    k - pow(val[i]
                                 - val[i - 1],
                                 2), i))
         
    # If index is at 0, find if
    # it is zero or one and
    # increment the count
    if (i == 0):
        if (arr[i] == 0):
            zero += 1
        else: one -= 1
 
        # If count of zero is not equal to
        # count of one, re-initialize
        # count_split with 0
        if (zero != one):
            count_split = 0
         
    # Store the returned value in dp[]
    dp[k][N] = count_split
    return dp[k][N]
 
# Driver Code
arr = [1, 0, 0, 1, 0, 1, 1, 0]
val = [9, 7, 5, 2, 4, 12, 3, 1]
k = 10
 
N = len(arr)
 
print(maximumSplits(arr, val, k, N))
 
# This code is contributed by Saurabh Jaiswal


C#




// C# program for the above approach
using System;
public class GFG
{
 
static int[,] dp = new int[1001, 1001];
 
// Function to find maximum possible splits
// in atmost k coins such that each
// segment contains equal number of 0 and 1
static int maximumSplits(int[] arr, int[] val,
                  int k, int N)
{
    // Base Case
    if (k < 0) {
        return Int32.MinValue;
    }
 
    // If already have a stored value
    // return it
    if (dp[k, N] != -1) {
        return dp[k, N];
    }
 
    // Count for zeros and ones
    int zero = 0, one = 0;
 
    // Count for number of splits
    int count_split = 0;
    int i;
 
    // Iterate over the array and
    // search for zeros and ones
    for (i = N - 1; i > 0; i--) {
        if(arr[i] == 0)
            zero++;
        else
            one++;
 
        // If count of zeros is equal to
        // count of ones
        if (zero == one) {
            // Store the maximum possible one
            count_split = Math.Max(
                count_split,
                1
                    + maximumSplits(
                          arr, val,
                          k - (int)Math.Pow(val[i]
                                      - val[i - 1],
                                  2),
                          i));
        }
    }
 
    // If index is at 0, find if
    // it is zero or one and
    // increment the count
    if (i == 0) {
        if(arr[0] == 0)
            zero++;
        else
            one++;
 
        // If count of zero is not equal to
        // count of one, re-initialize
        // count_split with 0
        if (zero != one) {
            count_split = 0;
        }
    }
 
    // Store the returned value in dp[]
    return dp[k, N] = count_split;
}
  
 
// Driver code
public static void Main(String[] args)
{
    int[] arr = { 1, 0, 0, 1, 0, 1, 1, 0 };
    int[] val = { 9, 7, 5, 2, 4, 12, 3, 1 };
    int k = 10;
 
    int N = arr.Length;
    int i, j;
    for(i=0;i<1001;i++)
    {
        for(j=0;j<1001;j++)
        {
            dp[i, j] = -1;
        }
    }
 
    Console.WriteLine(maximumSplits(arr, val, k, N));
}
}
 
// This code is contributed by sanjoy_62.


Javascript




<script>
 
      // JavaScript Program to implement
      // the above approach
      let dp = new Array(1001);
      for (let i = 0; i < dp.length; i++) {
          dp[i] = new Array(1001).fill(-1);
      }
       
      // Function to find maximum possible splits
      // in atmost k coins such that each
      // segment contains equal number of 0 and 1
      function maximumSplits(arr, val,
          k, N)
      {
       
          // Base Case
          if (k < 0) {
              return Number.MIN_VALUE;
          }
 
          // If already have a stored value
          // return it
          if (dp[k][N] != -1) {
              return dp[k][N];
          }
 
          // Count for zeros and ones
          let zero = 0, one = 0;
 
          // Count for number of splits
          let count_split = 0;
          let i;
 
          // Iterate over the array and
          // search for zeros and ones
          for (i = N - 1; i > 0; i--) {
              arr[i] == 0 ? zero++ : one++;
 
              // If count of zeros is equal to
              // count of ones
              if (zero == one)
              {
               
                  // Store the maximum possible one
                  count_split = Math.max(
                      count_split, 1
                      + maximumSplits(
                          arr, val,
                          k - Math.pow(val[i]
                              - val[i - 1],
                              2), i));
              }
          }
 
          // If index is at 0, find if
          // it is zero or one and
          // increment the count
          if (i == 0) {
              arr[0] == 0 ? zero++ : one++;
 
              // If count of zero is not equal to
              // count of one, re-initialize
              // count_split with 0
              if (zero != one) {
                  count_split = 0;
              }
          }
 
          // Store the returned value in dp[]
          return dp[k][N] = count_split;
      }
 
      // Driver Code
      let arr = [1, 0, 0, 1, 0, 1, 1, 0];
      let val = [9, 7, 5, 2, 4, 12, 3, 1];
      let k = 10;
 
      let N = arr.length;
 
      document.write(maximumSplits(arr, val, k, N))
 
  // This code is contributed by Potta Lokesh
  </script>


Output

2

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



Similar Reads

Minimize maximum array element possible by at most K splits on the given array
Given an array arr[] consisting of N positive integers and a positive integer K, the task is to minimize the maximum element present in the array by splitting at most K array elements into two numbers equal to their value. Examples: Input: arr[] = {2, 4, 8, 2}, K = 4Output: 2Explanation:Following sequence of operations are required to be performed:
9 min read
Maximum splits in binary string such that each substring is divisible by given odd number
Given binary string str, the task is to calculate the maximum possible splits possible to make each substring divisible by a given odd number K.Examples: Input: str = "110111001", K = 9 Output: 2 Explanation: The two possible substrings are "11011" and "1001". The equivalent decimal values are 27 and 9 respectively which are divisible by 9.Input: s
5 min read
Minimize splits in given Array to find subsets of at most 2 elements with sum at most K
Given an array arr[] of N integers and an integer K, the task is to calculate the minimum number of subsets of almost 2 elements the array can be divided such that the sum of elements in each subset is almost K. Examples: Input: arr[] = {1, 2, 3}, K = 3Output: 2Explanation: The given array can be divided into subsets as {1, 2} and {3}, and the sum
6 min read
Minimum splits in a binary string such that every substring is a power of 4 or 6.
Given a string S composed of 0 and 1. Find the minimum splits such that the substring is a binary representation of the power of 4 or 6 with no leading zeros. Print -1 if no such partitioning is possible. Examples: Input: 100110110 Output: 3 The string can be split into a minimum of three substrings 100(power of 4), 110 (power of 6) and 110(power o
11 min read
Longest Substring of A that can be changed to Substring of B in at most T cost
Given two strings A and B of the same length and two positive integers K and T. The task is to find the longest substring of A that can be converted to the same substring at the same position in B in less than or equal to T cost. Converting any character of A to any other character costs K units. Note: If multiple valid substrings are possible then
13 min read
Maximum number of splits of a binary number
Given a binary string S, the task is to find the maximum number of parts that you can split it into such that every part is divisible by 2. If the string can't be split satisfying the given conditions then print -1.Examples: Input: S = "100" Output: 2 The splits are as follows: "10" ans "0".Input: S = "110" Output: 1 Approach: This problem can be s
4 min read
Count possible splits of sum N into K integers such that the minimum is at least P
Given three integers N, P, and K, the task is to find the total number of ways to divide N into K integers having sum N where each integer is ? P. Examples: Input: K = 3, N = 8, P = 2Output: 6Explanation:Six possible solutions are: {2, 2, 4}, {2, 3, 3}, {2, 4, 2}, {3, 2, 3}, {3, 3, 2}, {4, 2, 2}Each of the above integers in all combinations are ? P
14 min read
Minimum possible value T such that at most D Partitions of the Array having at most sum T is possible
Given an array arr[] consisting of N integers and an integer D, the task is to find the least integer T such that the entire array can be partitioned into at most D subarrays from the given array with sum atmost T. Examples: Input: D = 5, arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} Output: 15 Explanation: If T = 15, then 5 subarrays {{1, 2, 3, 4, 5}, {
9 min read
Check if it is possible to obtain a Balanced Parenthesis by shifting brackets to either end at most K times
Given a string S of size N consisting of only '(' and ')' only and a positive integer K, the task is to check if the given string can be made a valid parenthesis sequence by moving any characters of the string S to either end of the string at most K number of times. Examples: Input: S = ")(", K = 1Output: YesExplanation: Move S[0] to the end of the
8 min read
Maximum partitions possible of given Array with cost at most K and equal count of odd and even elements
Given two integers N, K, and an array, arr[] of size N, containing an equal number of even and odd elements, and also given that the cost of partitioning the array by making a cut between index i and i+1 is equal to the abs(arr[i]-arr[i+1]), the task is to find the maximum partitions of the array, such that each partition has an equal number of odd
9 min read