Optimally accommodate 0s and 1s from a Binary String into K buckets

Given a binary string S, consisting of 0’s and 1’s. You have to accommodate the 0’s and 1’s into the K buckets in such a way that the following conditions are satisfied:
- You fill the 0’s and 1’s into the buckets preserving the relative order of 0’s and 1’s. For example, you cannot put S[1] into bucket 2 and S[0] into bucket 1. You have to preserve the original ordering of the binary string.
- No bucket should be left empty and no element in the string should be left unaccommodated.
- The sum of all the products of (number of 0’s * number of 1’s) for each bucket should be the minimum among all possible accommodation arrangements.
If a solution is not possible, then print -1.
Examples:
Input: S = "0001", K = 2
Output: 0
We have 3 choices {"0", "001"}, {"00", "01"}, {"000", 1}
First choice, we will get 1*0 + 2*1 = 2
Second choice, we will get 2*0 + 1*1 = 1
Third choice, we will get 3*0 + 0*1 = 0
Out of all the 3 choices, the third choice
is giving the minimum answer.
Input: S = "0101", K = 1
Output: 1
Recursive implementation: You have to accommodate binary string into K buckets without disturbing the above conditions. Then simple recursive solution can be made by first filling up i-th bucket (starting from 0) by putting elements from start to N (N = length of binary string) and keep adding count zeroes and ones till start index. For each iteration, if there x zeroes and y ones till start then recur for f(start, K) = x * y + f(start + 1, K – 1) because next accommodation will be made from (start + 1)-th index and remaining buckets will K – 1.
So, the recursive formula will be –
F(start, current_bucket) = | |
| min | F(i + 1, next_bucket) + (ones * zeroes in current_bucket)
| |
| i = start to N
Top-Down Dynamic Approach:
The recursive relation can be changed to Dynamic Solution by saving the results of different combinations of start and bucket variable into 2-D DP array. We can use the fact that the order of the string should be preserved. You can have a 2-D array saving the states of size [size of string * buckets], where dp[i][j] will tell us minimum value of accommodation till i’th index of the string using j + 1 buckets. Our final answer will be in dp[N-1][K-1].
Below is the implementation of the above approach:
C++
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std;// 2-D dp array saving different states// dp[i][j] = minimum value of accommodation// till i'th index of the string// using j+1 number of buckets.vector<vector<int> > dp;// Function to find the minimum required// sum using dynamic programmingint solveUtil(int start, int bucket, string str, int K){ int N = str.size(); // If both start and bucket reached end then // return 0 else that arrangement is not possible // so return INT_MAX if (start == N) { if (bucket == K) return 0; return INT_MAX; } // Corner case if (bucket == K) return INT_MAX; // If state if already calculated // then return its answer if (dp[start][bucket] != -1) return dp[start][bucket]; int zeroes = 0; int ones = 0; int ans = INT_MAX; // Start filling zeroes and ones which to be accommodated // in jth bucket then ans for current arrangement will be // ones*zeroes + recur(i+1, bucket+1) for (int i = start; i < N; ++i) { if (str[i] == '1') ones++; else zeroes++; if (ones * zeroes > ans) break; int temp = solveUtil(i + 1, bucket + 1, str, K); // If this arrangement is not possible then // don't calculate further if (temp != INT_MAX) { ans = min(ans, temp + (ones * zeroes)); } } return dp[start][bucket] = ans;}// Function to initialize the dp and call// solveUtil() method to get the answerint solve(string str, int K){ int N = str.size(); dp.clear(); dp.resize(N, vector<int>(K, -1)); // Start with 0-th index and 1 bucket int ans = solveUtil(0, 0, str, K); return ans == INT_MAX ? -1 : ans;}// Driver codeint main(){ string S = "0101"; // K buckets int K = 2; cout << solve(S, K) << endl; return 0;} |
Java
// Java implementation of the approachimport java.io.*;import java.util.*;class GFG{// 2-D dp array saving different states// dp[i][j] = minimum value of accommodation// till i'th index of the string// using j+1 number of buckets.static int[][] dp;// Function to find the minimum required// sum using dynamic programmingstatic int solveUtil(int start, int bucket, String str, int K){ int N = str.length(); // If both start and bucket reached end // then return 0 else that arrangement // is not possible so return INT_MAX if (start == N) { if (bucket == K) { return 0; } return Integer.MAX_VALUE; } // Corner case if (bucket == K) { return Integer.MAX_VALUE; } // If state if already calculated // then return its answer if (dp[start][bucket] != -1) { return dp[start][bucket]; } int zeroes = 0; int ones = 0; int ans = Integer.MAX_VALUE; // Start filling zeroes and ones which to be // accommodated in jth bucket then ans for // current arrangement will be // ones*zeroes + recur(i+1, bucket+1) for(int i = start; i < N; ++i) { if (str.charAt(i) == '1') { ones++; } else { zeroes++; } if (ones * zeroes > ans) { break; } int temp = solveUtil(i + 1, bucket + 1, str, K); // If this arrangement is not possible then // don't calculate further if (temp != Integer.MAX_VALUE) { ans = Math.min(ans, temp + (ones * zeroes)); } } return dp[start][bucket] = ans;}// Function to initialize the dp and call// solveUtil() method to get the answerstatic int solve(String str, int K){ int N = str.length(); dp = new int[N][K]; for(int[] row : dp) { Arrays.fill(row, -1); } // Start with 0-th index and 1 bucket int ans = solveUtil(0, 0, str, K); return ans == Integer.MAX_VALUE ? -1 : ans;}// Driver codepublic static void main(String[] args){ String S = "0101"; // K buckets int K = 2; System.out.println(solve(S, K));}}// This code is contributed by rag2127 |
Python3
# Python3 implementation of the approach# 2-D dp array saving different states# dp[i][j] = minimum value of accommodation# till i'th index of the string# using j+1 number of buckets.# Function to find the minimum required# sum using dynamic programmingdef solveUtil(start, bucket, str1, K,dp): N = len(str1) # If both start and bucket reached end then # return 0 else that arrangement is not possible # so return INT_MAX if (start == N) : if (bucket == K): return 0 return 10**9 # Corner case if (bucket == K): return 10**9 # If state if already calculated # then return its answer if (dp[start][bucket] != -1): return dp[start][bucket] zeroes = 0 ones = 0 ans = 10**9 # Start filling zeroes and ones which to be accommodated # in jth bucket then ans for current arrangement will be # ones*zeroes + recur(i+1, bucket+1) for i in range(start,N): if (str1[i] == '1'): ones += 1 else: zeroes += 1 if (ones * zeroes > ans): break temp = solveUtil(i + 1, bucket + 1, str1, K,dp) # If this arrangement is not possible then # don't calculate further if (temp != 10**9): ans = min(ans, temp + (ones * zeroes)) dp[start][bucket] = ans return ans# Function to initialize the dp and call# solveUtil() method to get the answerdef solve(str1, K): N = len(str1) dp = [[-1 for i in range(K)] for i in range(N)] # Start with 0-th index and 1 bucket ans = solveUtil(0, 0, str1, K,dp) if ans == 10**9: return -1 else: return ans# Driver codes = "0101"S=[i for i in s]# K bucketsK = 2print(solve(S, K))# This code is contributed by mohit kumar 29 |
C#
// C# implementation of the approachusing System;class GFG { // 2-D dp array saving different states // dp[i][j] = minimum value of accommodation // till i'th index of the string // using j+1 number of buckets. static int[,] dp; // Function to find the minimum required // sum using dynamic programming static int solveUtil(int start, int bucket, string str, int K) { int N = str.Length; // If both start and bucket reached end // then return 0 else that arrangement // is not possible so return INT_MAX if (start == N) { if (bucket == K) { return 0; } return Int32.MaxValue; } // Corner case if (bucket == K) { return Int32.MaxValue; } // If state if already calculated // then return its answer if (dp[start,bucket] != -1) { return dp[start, bucket]; } int zeroes = 0; int ones = 0; int ans = Int32.MaxValue; // Start filling zeroes and ones which to be // accommodated in jth bucket then ans for // current arrangement will be // ones*zeroes + recur(i+1, bucket+1) for(int i = start; i < N; ++i) { if (str[i] == '1') { ones++; } else { zeroes++; } if (ones * zeroes > ans) { break; } int temp = solveUtil(i + 1, bucket + 1, str, K); // If this arrangement is not possible then // don't calculate further if (temp != Int32.MaxValue) { ans = Math.Min(ans, temp + (ones * zeroes)); } } return dp[start, bucket] = ans; } // Function to initialize the dp and call // solveUtil() method to get the answer static int solve(string str, int K) { int N = str.Length; dp = new int[N, K]; for(int i = 0; i < N; i++) { for(int j = 0; j < K; j++) { dp[i, j] = -1; } } // Start with 0-th index and 1 bucket int ans = solveUtil(0, 0, str, K); return ans == Int32.MaxValue ? -1 : ans; } // Driver code static void Main() { string S = "0101"; // K buckets int K = 2; Console.WriteLine(solve(S, K)); }}// This code is contributed by divyeshrabadiya07. |
Javascript
<script>// Javascript implementation of the approach// 2-D dp array saving different states// dp[i][j] = minimum value of accommodation// till i'th index of the string// using j+1 number of buckets.let dp;// Function to find the minimum required// sum using dynamic programmingfunction solveUtil(start, bucket, str, K){ let N = str.length; // If both start and bucket reached end // then return 0 else that arrangement // is not possible so return INT_MAX if (start == N) { if (bucket == K) { return 0; } return Number.MAX_VALUE; } // Corner case if (bucket == K) { return Number.MAX_VALUE; } // If state if already calculated // then return its answer if (dp[start][bucket] != -1) { return dp[start][bucket]; } let zeroes = 0; let ones = 0; let ans = Number.MAX_VALUE; // Start filling zeroes and ones which to be // accommodated in jth bucket then ans for // current arrangement will be // ones*zeroes + recur(i+1, bucket+1) for(let i = start; i < N; ++i) { if (str[i] == '1') { ones++; } else { zeroes++; } if (ones * zeroes > ans) { break; } let temp = solveUtil(i + 1, bucket + 1, str, K); // If this arrangement is not possible then // don't calculate further if (temp != Number.MAX_VALUE) { ans = Math.min(ans, temp + (ones * zeroes)); } } return dp[start][bucket] = ans;}// Function to initialize the dp and call// solveUtil() method to get the answerfunction solve(str, K){ let N = str.length; dp = new Array(N); for(let i = 0; i < N; i++) { dp[i] = new Array(K); for(let j = 0; j < K; j++) { dp[i][j] = -1; } } // Start with 0-th index and 1 bucket let ans = solveUtil(0, 0, str, K); return ans == Number.MAX_VALUE ? -1 : ans;}// Driver codelet S = "0101"; // K bucketslet K = 2; document.write(solve(S, K));// This code is contributed by unknown2108</script> |
2
Time Complexity: O(N3)
Space Complexity: O(N2)
This solution is still not optimised because it calls the same state a number of times. So, now look into the Optimised Bottom Up DP Approach.
Bottom-Up Dynamic Approach: Let us try to think about the final state first. Here the variables are the number of buckets and the index of the string. Let dp[i][j] be the minimum sum of products for string elements 0 to j-1 and i buckets. Now to define our transition function, we will have to start from the back and consider partition at each possible position k. Hence our transition function looks like:
dp [i][j] = for all k = 0 to j min(dp[i][k-1] + numberOfZeroes * numberOfOnes)
for i = 0 (single partition) simple count number of 0's and 1's and do the multiplication.
And if number of buckets is more than string length till now ans is -1 as we cant fill all
the available buckets.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std;// Function to find the minimum required// sum using dynamic programmingint solve(string str, int K){ int n = str.length(); // dp[i][j] = minimum val of accommodation // till j'th index of the string // using i+1 number of buckets. // Final ans will be in dp[n-1][K-1] long long dp[K][n]; // Initialise dp with all states as 0 memset(dp, 0, sizeof dp); // Corner cases if (n < K) return -1; else if (n == K) return 0; // Filling first row, if only 1 bucket then simple count // number of zeros and ones and do the multiplication long long zeroes = 0, ones = 0; for (int i = 0; i < n; i++) { if (str[i] == '0') zeroes++; else ones++; dp[0][i] = ones * zeroes; } for (int s = 1; s < K; s++) { for (int i = 0; i < n; i++) { dp[s][i] = INT_MAX; ones = 0; zeroes = 0; for (int k = i; k >= 0; k--) { if (str[k] == '0') zeroes++; else ones++; // If k = 0 then this arrangement is not possible dp[s][i] = min(dp[s][i], +((k - 1 >= 0) ? ones * zeroes + dp[s - 1][k - 1] : INT_MAX)); } } } // If no arrangement is possible then // our answer will remain INT_MAX so return -1 return (dp[K - 1][n - 1] == INT_MAX) ? -1 : dp[K - 1][n - 1];}// Driver codeint main(){ string S = "0101"; // K buckets int K = 2; cout << solve(S, K) << endl; return 0;} |
Java
// Java implementation of the approachclass GFG{ // Function to find the minimum required // sum using dynamic programming static long solve(String str, int K) { int n = str.length(); // dp[i][j] = minimum val of accommodation // till j'th index of the string // using i+1 number of buckets. // Final ans will be in dp[n-1][K-1] long dp[][] = new long[K][n]; // Corner cases if (n < K) return -1; else if (n == K) return 0; // Filling first row, if only 1 bucket then simple count // number of zeros and ones and do the multiplication long zeroes = 0, ones = 0; for (int i = 0; i < n; i++) { if (str.charAt(i) == '0') zeroes++; else ones++; dp[0][i] = ones * zeroes; } for (int s = 1; s < K; s++) { for (int i = 0; i < n; i++) { dp[s][i] = Integer.MAX_VALUE; ones = 0; zeroes = 0; for (int k = i; k >= 0; k--) { if (str.charAt(k) == '0') zeroes++; else ones++; // If k = 0 then this arrangement is not possible dp[s][i] = Math.min(dp[s][i], +((k - 1 >= 0) ? ones * zeroes + dp[s - 1][k - 1] : Integer.MAX_VALUE)); } } } // If no arrangement is possible then // our answer will remain INT_MAX so return -1 return (dp[K - 1][n - 1] == Integer.MAX_VALUE) ? -1 : dp[K - 1][n - 1]; } // Driver code public static void main (String[] args) { String S = "0101"; // K buckets int K = 2; System.out.println(solve(S, K)); }}// This code is contributed by ihritik |
Python3
# Python3 implementation of the approach import sys# Function to find the minimum required # sum using dynamic programming def solve(Str, K): n = len(Str) # dp[i][j] = minimum val of accommodation # till j'th index of the string # using i+1 number of buckets. # Final ans will be in dp[n-1][K-1] # Initialise dp with all states as 0 dp = [[0 for i in range(n)] for j in range(K)] # Corner cases if(n < K): return -1 elif(n == K): return 0 # Filling first row, if only 1 bucket then simple count # number of zeros and ones and do the multiplication zeroes = 0 ones = 0 for i in range(n): if(Str[i] == '0'): zeroes += 1 else: ones += 1 dp[0][i] = ones * zeroes for s in range(1, K): for i in range(n): dp[s][i] = sys.maxsize ones = 0 zeroes = 0 for k in range(i, -1, -1): if(Str[k] == '0'): zeroes += 1 else: ones += 1 # If k = 0 then this arrangement # is not possible temp = 0 if(k - 1 >= 0): temp = ones * zeroes + dp[s - 1][k - 1] else: temp = sys.maxsize dp[s][i] = min(dp[s][i], temp) # If no arrangement is possible then # our answer will remain INT_MAX so return -1 if(dp[K - 1][n - 1] == sys.maxsize): return -1 else: return dp[K - 1][n - 1] # Driver code S = "0101"# K buckets K = 2print(solve(S, K))# This code is contributed by avanitrachhadiya2155 |
C#
// C# implementation of the approachusing System;class GFG{ // Function to find the minimum required // sum using dynamic programming static long solve(string str, int K) { int n = str.Length; // dp[i, j] = minimum val of accommodation // till j'th index of the string // using i+1 number of buckets. // Final ans will be in dp[n-1, K-1] long [, ] dp = new long[K, n]; // Corner cases if (n < K) return -1; else if (n == K) return 0; // Filling first row, if only 1 bucket then simple count // number of zeros and ones and do the multiplication long zeroes = 0, ones = 0; for (int i = 0; i < n; i++) { if (str[i] == '0') zeroes++; else ones++; dp[0, i] = ones * zeroes; } for (int s = 1; s < K; s++) { for (int i = 0; i < n; i++) { dp[s, i] = Int32.MaxValue; ones = 0; zeroes = 0; for (int k = i; k >= 0; k--) { if (str[k] == '0') zeroes++; else ones++; // If k = 0 then this arrangement is not possible dp[s, i] = Math.Min(dp[s, i], +((k - 1 >= 0) ? ones * zeroes + dp[s - 1, k - 1] : Int32.MaxValue)); } } } // If no arrangement is possible then // our answer will remain INT_MAX so return -1 return (dp[K - 1, n - 1] == Int32.MaxValue) ? -1 : dp[K - 1, n - 1]; } // Driver code public static void Main (string[] args) { string S = "0101"; // K buckets int K = 2; Console.WriteLine(solve(S, K)); } }// This code is contributed by ihritik |
Javascript
<script>// JavaScript implementation of the approach // Function to find the minimum required // sum using dynamic programming function solve(str,K) { let n = str.length; // dp[i][j] = minimum val of accommodation // till j'th index of the string // using i+1 number of buckets. // Final ans will be in dp[n-1][K-1] let dp = new Array(K); for(let i=0;i<K;i++) { dp[i]=new Array(n); for(let j=0;j<n;j++) { dp[i][j]=0; } } // Corner cases if (n < K) return -1; else if (n == K) return 0; // Filling first row, if only 1 bucket then simple count // number of zeros and ones and do the multiplication let zeroes = 0, ones = 0; for (let i = 0; i < n; i++) { if (str[i] == '0') zeroes++; else ones++; dp[0][i] = ones * zeroes; } for (let s = 1; s < K; s++) { for (let i = 0; i < n; i++) { dp[s][i] = Number.MAX_VALUE; ones = 0; zeroes = 0; for (let k = i; k >= 0; k--) { if (str[k] == '0') zeroes++; else ones++; // If k = 0 then this // arrangement is not possible dp[s][i] = Math.min(dp[s][i], +((k - 1 >= 0) ? ones * zeroes + dp[s - 1][k - 1] : Number.MAX_VALUE)); } } } // If no arrangement is possible then // our answer will remain INT_MAX so return -1 return (dp[K - 1][n - 1] == Number.MAX_VALUE) ? -1 : dp[K - 1][n - 1]; } // Driver code let S = "0101"; // K buckets let K = 2; document.write(solve(S, K));// This code is contributed by patel2127</script> |
2
Time Complexity: O(N3)
Space Complexity: O(N2)
Efficient approach : Space optimization
In previous approach the current value dp[s][i] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.
Implementation steps:
- Create a 1D vector dp of size n.
- Set corner cases and base case by initializing the values of DP .
- Create 2 values zeros and ones to store count.
- Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
- At last return the answer if exists in dp[n – 1] else return -1.
Implementation:
C++
// C++ implementation of the approach#include <bits/stdc++.h>using namespace std;// Function to find the minimum required// sum using dynamic programmingint solve(string str, int K){ int n = str.length(); // dp[i][j] = minimum val of accommodation // till j'th index of the string // using i+1 number of buckets. // Final ans will be in dp[n-1][K-1] vector<long long> dp(n); // Corner cases if (n < K) return -1; else if (n == K) return 0; // Filling first row, if only 1 bucket then simple count // number of zeros and ones and do the multiplication long long zeroes = 0, ones = 0; for (int i = 0; i < n; i++) { if (str[i] == '0') zeroes++; else ones++; dp[i] = ones * zeroes; } for (int s = 1; s < K; s++) { for (int i = n-1; i >= 0; i--) { dp[i] = INT_MAX; ones = 0; zeroes = 0; for (int k = i; k >= 0; k--) { if (str[k] == '0') zeroes++; else ones++; // If k = 0 then this arrangement is not possible dp[i] = min(dp[i], +((k - 1 >= 0) ? ones * zeroes + dp[k - 1] : INT_MAX)); } } } // If no arrangement is possible then // our answer will remain INT_MAX so return -1 return (dp[n - 1] == INT_MAX) ? -1 : dp[n - 1];}// Driver codeint main(){ string S = "0101"; // K buckets int K = 2; cout << solve(S, K) << endl; return 0;} |
Java
import java.util.*;public class Main { public static int solve(String str, int K) { int n = str.length(); // dp[i][j] = minimum val of accommodation // till j'th index of the string // using i+1 number of buckets. // Final ans will be in dp[n-1][K-1] int[] dp = new int[n]; Arrays.fill(dp, Integer.MAX_VALUE); // Corner cases if (n < K) return -1; else if (n == K) return 0; // Filling first row, if only 1 bucket then simple count // number of zeros and ones and do the multiplication long zeroes = 0, ones = 0; for (int i = 0; i < n; i++) { if (str.charAt(i) == '0') zeroes++; else ones++; dp[i] = (int) (ones * zeroes); } for (int s = 1; s < K; s++) { for (int i = n-1; i >= 0; i--) { ones = 0; zeroes = 0; for (int k = i; k >= 0; k--) { if (str.charAt(k) == '0') zeroes++; else ones++; // If k = 0 then this arrangement is not possible if (k - 1 >= 0) dp[i] = Math.min(dp[i], (int) (ones * zeroes + dp[k - 1])); else dp[i] = Math.min(dp[i], (int) (ones * zeroes)); } } } // If no arrangement is possible then // our answer will remain Integer.MAX_VALUE so return -1 return (dp[n - 1] == Integer.MAX_VALUE) ? -1 : dp[n - 1]; } // Driver code public static void main(String[] args) { String S = "0101"; int K = 2; System.out.println(solve(S, K)); }} |
Python3
# Python implementation of the approachimport sys# Function to find the minimum required# sum using dynamic programmingdef solve(s, k): n = len(s) # dp[i] = minimum val of accommodation # till i'th index of the string # using k+1 number of buckets. # Final ans will be in dp[n-1] dp = [0] * n # Corner cases if n < k: return -1 elif n == k: return 0 # Filling first row, if only 1 bucket then simple count # number of zeros and ones and do the multiplication zeroes, ones = 0, 0 for i in range(n): if s[i] == '0': zeroes += 1 else: ones += 1 dp[i] = ones * zeroes for s_ in range(1, k): for i in range(n-1, -1, -1): dp[i] = sys.maxsize ones, zeroes = 0, 0 for k_ in range(i, -1, -1): if s[k_] == '0': zeroes += 1 else: ones += 1 # If k_ = 0 then this arrangement is not possible dp[i] = min(dp[i], ((ones * zeroes + dp[k_ - 1]) if k_ - 1 >= 0 else sys.maxsize)) # If no arrangement is possible then # our answer will remain sys.maxsize so return -1 return -1 if dp[n - 1] == sys.maxsize else dp[n - 1]# Driver codeif __name__ == '__main__': S = "0101" # K buckets K = 2 print(solve(S, K)) |
C#
// C# implementation of the approachusing System;using System.Collections.Generic;public class GFG { // Function to find the minimum required // sum using dynamic programming static int Solve(string str, int K) { int n = str.Length; // dp[i] = minimum val of accommodation // till j'th index of the string // using i+1 number of buckets. // Final ans will be in dp[n-1][K-1] long[] dp = new long[n]; // Corner cases if (n < K) return -1; else if (n == K) return 0; // Filling first row, if only 1 bucket then simple // count number of zeros and ones and do the // multiplication long zeroes = 0, ones = 0; for (int i = 0; i < n; i++) { if (str[i] == '0') zeroes++; else ones++; dp[i] = ones * zeroes; } for (int s = 1; s < K; s++) { for (int i = n - 1; i >= 0; i--) { dp[i] = int.MaxValue; ones = 0; zeroes = 0; for (int k = i; k >= 0; k--) { if (str[k] == '0') zeroes++; else ones++; // If k = 0 then this arrangement is not // possible dp[i] = Math.Min( dp[i], ((k - 1 >= 0) ? ones * zeroes + dp[k - 1] : int.MaxValue)); } } } // If no arrangement is possible then // our answer will remain int.MaxValue so return -1 return (dp[n - 1] == int.MaxValue) ? -1 : (int)dp[n - 1]; } // Driver code static void Main(string[] args) { string S = "0101"; // K buckets int K = 2; Console.WriteLine(Solve(S, K)); }} |
Javascript
// Function to find the minimum required// sum using dynamic programmingfunction solve(str, K) { let n = str.length; // dp[i][j] = minimum val of accommodation // till j'th index of the string // using i+1 number of buckets. // Final ans will be in dp[n-1][K-1] let dp = Array(n); // Corner cases if (n < K) return -1; else if (n == K) return 0; // Filling first row, if only 1 bucket then simple count // number of zeros and ones and do the multiplication let zeroes = 0, ones = 0; for (let i = 0; i < n; i++) { if (str[i] == '0') zeroes++; else ones++; dp[i] = ones * zeroes; } for (let s = 1; s < K; s++) { for (let i = n-1; i >= 0; i--) { dp[i] = Number.MAX_VALUE; ones = 0; zeroes = 0; for (let k = i; k >= 0; k--) { if (str[k] == '0') zeroes++; else ones++; // If k = 0 then this arrangement is not possible dp[i] = Math.min(dp[i], +((k - 1 >= 0) ? ones * zeroes + dp[k - 1] : Number.MAX_VALUE)); } } } // If no arrangement is possible then // our answer will remain INT_MAX so return -1 return (dp[n - 1] == Number.MAX_VALUE) ? -1 : dp[n - 1];}// Driver codelet S = "0101";// K bucketslet K = 2;console.log(solve(S, K)); |
Output:
2
Time Complexity: O(n*K^2)
Auxiliary Space: O(N)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



