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++ 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 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 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# 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. |
<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++ 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 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 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# 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 |
<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++ 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;
} |
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));
}
} |
# 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# 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));
}
} |
// 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)