Split a binary string into K subsets minimizing sum of products of occurrences of 0 and 1
Last Updated :
09 Feb, 2022
Given a binary string S, the task is to partition the sequence into K non-empty subsets such that the sum of products of occurrences of 0 and 1 for all subsets is minimum. If impossible print -1.
Examples:
Input: S = “0001”, K = 2
Output: 0
Explanation
We have 3 choices {0, 001}, {00, 01}, {000, 1}
The respective sum of products are {1*0 + 2*1 = 2}, {2*0 + 1*1 = 1}, {3*0 + 0*1 = 0}.
Input: S = “1011000110110100”, K = 5
Output: 8
Explanation: The subsets {10, 11, 000, 11011, 0100} minimizes the sum of product { 1*1 + 0*2 + 3*0 + 1*4 + 3*1 = 8 }.
Approach: In order to solve this problem we are using bottom-up dynamic programming.
- We calculate the minimum sum of products for all subsets and then, for every subset we use this value to compute the minimum sum of products for all sizes of that subset.
- For a subset starting at index i and ending at index j the value will be minimum of dp[i-1] + (count_zero * count_one) where count_zero and count_one are the occurrences of 0 and 1 between i and j respectively.
- For each index j, we find the minimum value amongst all possible values of i.
- Return dp[N – 1] for the final answer.
Below code is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minSumProd(string S, int K)
{
int len = S.length();
if (K > len)
return -1;
if (K == len)
return 0;
vector< int > dp(len);
int count_zero = 0, count_one = 0;
for ( int j = 0; j < len; j++) {
(S[j] == '0' )
? count_zero++
: count_one++;
dp[j] = count_zero * count_one;
}
for ( int i = 1; i < K; i++) {
for ( int j = len; j >= i; j--) {
count_zero = 0, count_one = 0;
dp[j] = INT_MAX;
for ( int k = j; k >= i; k--) {
(S[k] == '0' ) ? count_zero++
: count_one++;
dp[j]
= min(
dp[j],
count_zero * count_one
+ dp[k - 1]);
}
}
}
return dp[len - 1];
}
int main()
{
string S = "1011000110110100" ;
int K = 5;
cout << minSumProd(S, K) << '\n' ;
return 0;
}
|
Java
import java.util.*;
class GFG{
static int minSumProd(String S, int K)
{
int len = S.length();
if (K > len)
return - 1 ;
if (K == len)
return 0 ;
int []dp = new int [len];
int count_zero = 0 , count_one = 0 ;
for ( int j = 0 ; j < len; j++)
{
if (S.charAt(j) == '0' )
count_zero++;
else
count_one++;
dp[j] = count_zero * count_one;
}
for ( int i = 1 ; i < K; i++)
{
for ( int j = len- 1 ; j >= i; j--)
{
count_zero = 0 ;
count_one = 0 ;
dp[j] = Integer.MAX_VALUE;
for ( int k = j; k >= i; k--)
{
if (S.charAt(k) == '0' )
count_zero++;
else
count_one++;
dp[j] = Math.min(dp[j], count_zero *
count_one +
dp[k - 1 ]);
}
}
}
return dp[len - 1 ];
}
public static void main(String[] args)
{
String S = "1011000110110100" ;
int K = 5 ;
System.out.print(minSumProd(S, K));
}
}
|
Python3
import sys
def minSumProd(S, K):
Len = len (S);
if (K > Len ):
return - 1 ;
if (K = = Len ):
return 0 ;
dp = [ 0 ] * Len ;
count_zero = 0 ;
count_one = 0 ;
for j in range ( 0 , Len , 1 ):
if (S[j] = = '0' ):
count_zero + = 1 ;
else :
count_one + = 1 ;
dp[j] = count_zero * count_one;
for i in range ( 1 , K):
for j in range ( Len - 1 , i - 1 , - 1 ):
count_zero = 0 ;
count_one = 0 ;
dp[j] = sys.maxsize;
for k in range (j, i - 1 , - 1 ):
if (S[k] = = '0' ):
count_zero + = 1 ;
else :
count_one + = 1 ;
dp[j] = min (dp[j], count_zero *
count_one +
dp[k - 1 ]);
return dp[ Len - 1 ];
if __name__ = = '__main__' :
S = "1011000110110100" ;
K = 5 ;
print (minSumProd(S, K));
|
C#
using System;
class GFG{
static int minSumProd( string S, int K)
{
int len = S.Length;
if (K > len)
return -1;
if (K == len)
return 0;
int []dp = new int [len];
int count_zero = 0, count_one = 0;
for ( int j = 0; j < len; j++)
{
if (S[j] == '0' )
{
count_zero++;
}
else
{
count_one++;
}
dp[j] = count_zero * count_one;
}
for ( int i = 1; i < K; i++)
{
for ( int j = len - 1; j >= i; j--)
{
count_zero = 0;
count_one = 0;
dp[j] = Int32.MaxValue;
for ( int k = j; k >= i; k--)
{
if (S[k] == '0' )
{
count_zero++;
}
else
{
count_one++;
}
dp[j] = Math.Min(dp[j], count_zero *
count_one +
dp[k - 1]);
}
}
}
return dp[len - 1];
}
public static void Main( string [] args)
{
string S = "1011000110110100" ;
int K = 5;
Console.Write(minSumProd(S, K));
}
}
|
Javascript
<script>
function minSumProd(S, K) {
let len = S.length;
if (K > len)
return -1;
if (K == len)
return 0;
let dp = new Array(len);
let count_zero = 0, count_one = 0;
for (let j = 0; j < len; j++) {
(S[j] == '0' )
? count_zero++
: count_one++;
dp[j] = count_zero * count_one;
}
for (let i = 1; i < K; i++) {
for (let j = len; j >= i; j--) {
count_zero = 0, count_one = 0;
dp[j] = Number.MAX_SAFE_INTEGER;
for (let k = j; k >= i; k--) {
(S[k] == '0' ) ? count_zero++
: count_one++;
dp[j]
= Math.min(
dp[j],
count_zero * count_one
+ dp[k - 1]);
}
}
}
return dp[len - 1];
}
let S = "1011000110110100" ;
let K = 5;
document.write(minSumProd(S, K));
</script>
|
Time Complexity: O(K*N*N)
Auxiliary Space Complexity: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...