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 programming int 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 answer int 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 code int main() { string S = "0101" ; // K buckets int K = 2; cout << solve(S, K) << endl; return 0; } |
Java
// Java implementation of the approach import 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 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 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 answer static 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 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 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 programming def 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 answer def 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 code s = "0101" S = [i for i in s] # K buckets K = 2 print (solve(S, K)) # This code is contributed by mohit kumar 29 |
C#
// C# implementation of the approach using 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 programming function 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 answer function 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 code let S = "0101" ; // K buckets let 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 programming 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] 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 code int main() { string S = "0101" ; // K buckets int K = 2; cout << solve(S, K) << endl; return 0; } |
Java
// Java implementation of the approach 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.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 = 2 print (solve(S, K)) # This code is contributed by avanitrachhadiya2155 |
C#
// C# implementation of the approach using 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 programming 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] 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 code int 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 approach import sys # Function to find the minimum required # sum using dynamic programming def 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 code if __name__ = = '__main__' : S = "0101" # K buckets K = 2 print (solve(S, K)) |
C#
// C# implementation of the approach using 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 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 = 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 code let S = "0101" ; // K buckets let 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 neveropen!