Оптимально разместить нули и единицы из двоичной строки в 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 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, 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 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, 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 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 str1ing# 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, 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 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, 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++) {  
РЕКОМЕНДУЕМЫЕ СТАТЬИ |