📌  相关文章
📜  最大可能的平衡二进制子串拆分,成本为 K

📅  最后修改于: 2022-05-13 01:56:04.531000             🧑  作者: Mango

最大可能的平衡二进制子串拆分,成本为 K

给定一个二进制数组arr[]和一个值数组val[] 。任务是找到二进制数组的最大可能拆分,使得每个段包含相同数量的01 ,最多使用k个硬币。每个拆分成本(val[i] – val[j]) 2 ,其中ij是拆分段的相邻索引。

例子:

方法:可以使用动态规划(自顶向下方法)解决任务。
请按照以下步骤操作:

  1. 初始化一个二维矩阵,比如dp ,维度为 K * N。
  2. 对于每个索引,只要 0 和 1 的数量相等,就有两种选择,是否在该索引处进行切割或不在该索引处进行切割。
  3. 记住值,以便再次使用
  4. 最大化count_splits的值,以获得由此产生的最大削减。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
int dp[1001][1001];
 
// Function to find maximum possible splits
// in atmost k coins such that each
// segment contains equal number of 0 and 1
int maximumSplits(int arr[], int val[],
                  int k, int N)
{
    // Base Case
    if (k < 0) {
        return INT_MIN;
    }
 
    // If already have a stored value
    // return it
    if (dp[k][N] != -1) {
        return dp[k][N];
    }
 
    // Count for zeros and ones
    int zero = 0, one = 0;
 
    // Count for number of splits
    int count_split = 0;
    int i;
 
    // Iterate over the array and
    // search for zeros and ones
    for (i = N - 1; i > 0; i--) {
        arr[i] == 0 ? zero++ : one++;
 
        // If count of zeros is equal to
        // count of ones
        if (zero == one) {
            // Store the maximum possible one
            count_split = max(
                count_split,
                1
                    + maximumSplits(
                          arr, val,
                          k - pow(val[i]
                                      - val[i - 1],
                                  2),
                          i));
        }
    }
 
    // If index is at 0, find if
    // it is zero or one and
    // increment the count
    if (i == 0) {
        arr[0] == 0 ? zero++ : one++;
 
        // If count of zero is not equal to
        // count of one, re-initialize
        // count_split with 0
        if (zero != one) {
            count_split = 0;
        }
    }
 
    // Store the returned value in dp[]
    return dp[k][N] = count_split;
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 0, 0, 1, 0, 1, 1, 0 };
    int val[] = { 9, 7, 5, 2, 4, 12, 3, 1 };
    int k = 10;
 
    int N = sizeof(arr) / sizeof(arr[0]);
    memset(dp, -1, sizeof(dp));
 
    cout << maximumSplits(arr, val, k, N);
 
    return 0;
}


Java
// Java program for the above approach
public class GFG
{
 
static int[][] dp = new int[1001][1001];
 
// Function to find maximum possible splits
// in atmost k coins such that each
// segment contains equal number of 0 and 1
static int maximumSplits(int[] arr, int[] val,
                  int k, int N)
{
   
    // Base Case
    if (k < 0) {
        return Integer.MIN_VALUE;
    }
 
    // If already have a stored value
    // return it
    if (dp[k][N] != -1) {
        return dp[k][N];
    }
 
    // Count for zeros and ones
    int zero = 0, one = 0;
 
    // Count for number of splits
    int count_split = 0;
    int i;
 
    // Iterate over the array and
    // search for zeros and ones
    for (i = N - 1; i > 0; i--) {
        if(arr[i] == 0)
            zero++;
        else
            one++;
 
        // If count of zeros is equal to
        // count of ones
        if (zero == one) {
            // Store the maximum possible one
            count_split = Math.max(
                count_split,
                1
                    + maximumSplits(
                          arr, val,
                          k - (int)Math.pow(val[i]
                                      - val[i - 1],
                                  2),
                          i));
        }
    }
 
    // If index is at 0, find if
    // it is zero or one and
    // increment the count
    if (i == 0) {
        if(arr[0] == 0)
            zero++;
        else
            one++;
 
        // If count of zero is not equal to
        // count of one, re-initialize
        // count_split with 0
        if (zero != one) {
            count_split = 0;
        }
    }
 
    // Store the returned value in dp[]
    return dp[k][N] = count_split;
}
  
 
// Driver code
public static void main(String[] args)
{
    int[] arr = { 1, 0, 0, 1, 0, 1, 1, 0 };
    int[] val = { 9, 7, 5, 2, 4, 12, 3, 1 };
    int k = 10;
 
    int N = arr.length;
    int i, j;
    for(i=0;i<1001;i++)
    {
        for(j=0;j<1001;j++)
        {
            dp[i][j] = -1;
        }
    }
 
    System.out.println(maximumSplits(arr, val, k, N));
}
}
 
// This code is contributed by AnkThon


Python3
# Python Program to implement
# the above approach
dp = [0] * 1001
for i in range(len(dp)):
    dp[i] = [-1] * 1001
 
# Function to find maximum possible splits
# in atmost k coins such that each
# segment contains equal number of 0 and 1
def maximumSplits(arr, val, k, N):
 
    # Base Case
    if (k < 0):
        return 10 ** (-9)
     
    # If already have a stored value
    # return it
    if (dp[k][N] != -1) :
        return dp[k][N]
     
    # Count for zeros and ones
    zero = 0
    one = 0
 
    # Count for number of splits
    count_split = 0
 
    # Iterate over the array and
    # search for zeros and ones
    for i in range(N - 1, 0, -1):
        if (arr[i] == 0):
            zero += 1
        else: one += 1
 
        # If count of zeros is equal to
        # count of ones
        if (zero == one):
 
            # Store the maximum possible one
            count_split = max(
                count_split, 1
                + maximumSplits(
                    arr, val,
                    k - pow(val[i]
                                 - val[i - 1],
                                 2), i))
         
    # If index is at 0, find if
    # it is zero or one and
    # increment the count
    if (i == 0):
        if (arr[i] == 0):
            zero += 1
        else: one -= 1
 
        # If count of zero is not equal to
        # count of one, re-initialize
        # count_split with 0
        if (zero != one):
            count_split = 0
         
    # Store the returned value in dp[]
    dp[k][N] = count_split
    return dp[k][N]
 
# Driver Code
arr = [1, 0, 0, 1, 0, 1, 1, 0]
val = [9, 7, 5, 2, 4, 12, 3, 1]
k = 10
 
N = len(arr)
 
print(maximumSplits(arr, val, k, N))
 
# This code is contributed by Saurabh Jaiswal


C#
// C# program for the above approach
using System;
public class GFG
{
 
static int[,] dp = new int[1001, 1001];
 
// Function to find maximum possible splits
// in atmost k coins such that each
// segment contains equal number of 0 and 1
static int maximumSplits(int[] arr, int[] val,
                  int k, int N)
{
    // Base Case
    if (k < 0) {
        return Int32.MinValue;
    }
 
    // If already have a stored value
    // return it
    if (dp[k, N] != -1) {
        return dp[k, N];
    }
 
    // Count for zeros and ones
    int zero = 0, one = 0;
 
    // Count for number of splits
    int count_split = 0;
    int i;
 
    // Iterate over the array and
    // search for zeros and ones
    for (i = N - 1; i > 0; i--) {
        if(arr[i] == 0)
            zero++;
        else
            one++;
 
        // If count of zeros is equal to
        // count of ones
        if (zero == one) {
            // Store the maximum possible one
            count_split = Math.Max(
                count_split,
                1
                    + maximumSplits(
                          arr, val,
                          k - (int)Math.Pow(val[i]
                                      - val[i - 1],
                                  2),
                          i));
        }
    }
 
    // If index is at 0, find if
    // it is zero or one and
    // increment the count
    if (i == 0) {
        if(arr[0] == 0)
            zero++;
        else
            one++;
 
        // If count of zero is not equal to
        // count of one, re-initialize
        // count_split with 0
        if (zero != one) {
            count_split = 0;
        }
    }
 
    // Store the returned value in dp[]
    return dp[k, N] = count_split;
}
  
 
// Driver code
public static void Main(String[] args)
{
    int[] arr = { 1, 0, 0, 1, 0, 1, 1, 0 };
    int[] val = { 9, 7, 5, 2, 4, 12, 3, 1 };
    int k = 10;
 
    int N = arr.Length;
    int i, j;
    for(i=0;i<1001;i++)
    {
        for(j=0;j<1001;j++)
        {
            dp[i, j] = -1;
        }
    }
 
    Console.WriteLine(maximumSplits(arr, val, k, N));
}
}
 
// This code is contributed by sanjoy_62.


Javascript


输出
2

时间复杂度 O(N*K)
辅助空间:O(N*K)