Оптимально разместить нули и единицы из двоичной строки в K сегментов
Дана двоичная строка S , состоящая из нулей и единиц. Вы должны разместить 0 и 1 в K сегментов таким образом, чтобы выполнялись следующие условия:
- Вы заполняете ведра нулями и единицей, сохраняя относительный порядок нулей и единиц. Например, вы не можете поместить S [1] в сегмент 2 и S [0] в сегмент 1. Вы должны сохранить исходный порядок двоичной строки.
- Ни одно ведро не должно оставаться пустым, и ни один элемент в строке не должен оставаться неаккомодированным.
- Сумма всех произведений (количество нулей * количество единиц) для каждого ведра должна быть минимальной среди всех возможных вариантов размещения.
Если решение невозможно, выведите -1.
Примеры:
Ввод: S = "0001", K = 2 Выход: 0 У нас есть 3 варианта: {"0", "001"}, {"00", "01"}, {"000", 1} При первом выборе мы получим 1 * 0 + 2 * 1 = 2 Второй вариант, мы получим 2 * 0 + 1 * 1 = 1 Третий вариант, мы получим 3 * 0 + 0 * 1 = 0 Из всех трех вариантов третий вариант дает минимальный ответ. Ввод: S = "0101", K = 1 Выход: 1
Рекурсивная реализация: вы должны разместить двоичную строку в K сегментов, не нарушая вышеуказанных условий. Затем можно сделать простое рекурсивное решение, сначала заполнив i-е ведро (начиная с 0), поместив элементы от начала до N (N = длина двоичной строки) и продолжая добавлять счетные нули и единицы до начального индекса. Для каждой итерации, если до начала осталось x нулей и y единиц, то повторяется для f (start, K) = x * y + f (start + 1, K - 1), потому что следующее размещение будет выполнено с (start + 1) - -й индекс и оставшиеся сегменты будут K - 1.
Итак, рекурсивная формула будет -
F(start, current_bucket) = | | | min | F(i + 1, next_bucket) + (ones * zeroes in current_bucket) | | | i = start to N
Нисходящий динамический подход:
Рекурсивное отношение можно изменить на динамическое решение , сохранив результаты различных комбинаций переменной start и bucket в двумерном массиве DP. Мы можем использовать тот факт, что порядок строки должен быть сохранен. Вы можете иметь двумерный массив, сохраняющий состояния размера [размер строки * ведра] , где dp [i] [j] сообщит нам минимальное значение размещения до i-го индекса строки с использованием j + 1 ведер. Наш окончательный ответ будет в 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, buket+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 initialze 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, buket+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 initialze 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 str1ing # 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, buket+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 initialze 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, buket+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 initialze 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++) {  
РЕКОМЕНДУЕМЫЕ СТАТЬИ |