📌  相关文章
📜  最小化给定二进制字符串中设置位与未设置位交换的成本

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

最小化给定二进制字符串中设置位与未设置位交换的成本

给定一个大小为N的二进制字符串S ,任务是通过将每个已设置的位与未设置的位交换来找到最小成本,使得在索引ij处交换位对的成本为abs(j – i)

注意:交换位不能交换两次,并且给定二进制字符串中设置位的计数最多为N/2

例子:

方法:可以使用动态编程解决给定的问题,方法是将设置和未设置位的索引存储在两个辅助数组中,比如A[]B[] ,然后找到数组元素A[]与任意数组B[]的元素。请按照以下步骤解决给定的问题:

  • 初始化两个数组,比如A[]B[] ,并在其中存储 set 和 unset 位的索引。
  • 初始化一个二维数组, dp[][] ,维度为K*(N – K) ,其中 K 是S中设置位的计数,这样dp[i][j]存储交换第i数组元素A的最小成本[]与第j数组元素B[]
  • 现在,对于每个州,都有两个选择:
    1. 将第i数组元素A[]交换到第(j – 1)数组元素B[]dp[i][j] = dp[i][j – 1]
    2. 将第(i – 1)数组元素A[]交换到第(j – 1)数组元素B[]和第i数组元素A[]第 j数组元素B[] ,此状态可以计算为dp[i][j] = dp[i – 1][j – 1] + abs(A[i] – B[i])
  • 现在,选择上述两个选项中的最小值以找到当前状态:
  • 完成上述步骤后,打印dp[K][N – K]的值作为结果的最小操作数。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
#define INF 1000000000
 
// Function to find the minimum cost
// required to swap every set bit with
// an unset bit
int minimumCost(string s)
{
    int N = s.length();
 
    // Stores the indices of set and
    // unset bits of the string S
    vector A, B;
 
    // Traverse the string S
    for (int i = 0; i < N; i++) {
 
        // Store the indices
        if (s[i] == '1') {
            A.push_back(i);
        }
        else {
            B.push_back(i);
        }
    }
 
    int n1 = A.size();
    int n2 = B.size();
 
    // Initialize a dp table of size
    // n1*n2
    int dp[n1 + 1][n2 + 1];
 
    // Initialize all states to 0
    memset(dp, 0, sizeof(dp));
 
    // Set unreachable states to INF
    for (int i = 1; i <= n1; i++) {
        dp[i][0] = INF;
    }
 
    // Fill the dp Table according to
    // the given recurrence relation
    for (int i = 1; i <= n1; i++) {
        for (int j = 1; j <= n2; j++) {
 
            // Update the value of
            // dp[i][j]
            dp[i][j] = min(
                dp[i][j - 1],
                dp[i - 1][j - 1]
                    + abs(A[i - 1] - B[j - 1]));
        }
    }
 
    // Return the minimum cost
    return dp[n1][n2];
}
 
// Driver Code
int main()
{
    string S = "1010001";
    cout << minimumCost(S);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
static final int INF = 1000000000;
 
// Function to find the minimum cost
// required to swap every set bit with
// an unset bit
static int minimumCost(String s)
{
    int N = s.length();
 
    // Stores the indices of set and
    // unset bits of the String S
    Vector A = new Vector();
    Vector B = new Vector();
 
    // Traverse the String S
    for (int i = 0; i < N; i++) {
 
        // Store the indices
        if (s.charAt(i) == '1') {
            A.add(i);
        }
        else {
            B.add(i);
        }
    }
 
    int n1 = A.size();
    int n2 = B.size();
 
    // Initialize a dp table of size
    // n1*n2
    int [][]dp = new int[n1 + 1][n2 + 1];
 
 
    // Set unreachable states to INF
    for (int i = 1; i <= n1; i++) {
        dp[i][0] = INF;
    }
 
    // Fill the dp Table according to
    // the given recurrence relation
    for (int i = 1; i <= n1; i++) {
        for (int j = 1; j <= n2; j++) {
 
            // Update the value of
            // dp[i][j]
            dp[i][j] = Math.min(
                dp[i][j - 1],
                dp[i - 1][j - 1]
                    + Math.abs(A.get(i - 1) - B.get(j - 1)));
        }
    }
 
    // Return the minimum cost
    return dp[n1][n2];
}
 
// Driver Code
public static void main(String[] args)
{
    String S = "1010001";
    System.out.print(minimumCost(S));
}
}
 
// This code is contributed by shikhasingrajput


Python3
# Python program for the above approach
INF = 1000000000;
 
# Function to find the minimum cost
# required to swap every set bit with
# an unset bit
def minimumCost(s):
  N = len(s);
 
  # Stores the indices of set and
  # unset bits of the string S
  A = []
  B = []
 
  # Traverse the string S
  for i in range(0, N):
     
    # Store the indices
    if (s[i] == "1"):
      A.append(i);
    else:
      B.append(i);
     
  n1 = len(A)
  n2 = len(B)
 
  # Initialize a dp table of size
  # n1*n2
  dp = [[0 for i in range(n2 + 1)] for j in range(n1 + 1)]
 
  # Set unreachable states to INF
  for i in range(1, n1 + 1):
    dp[i][0] = INF
   
  # Fill the dp Table according to
  # the given recurrence relation
  for i in range(1, n1 + 1):
    for j in range(1, n2 + 1):
       
      # Update the value of
      # dp[i][j]
      dp[i][j] = min(
        dp[i][j - 1],
        dp[i - 1][j - 1] + abs(A[i - 1] - B[j - 1])
      );
     
  # Return the minimum cost
  return dp[n1][n2];
 
# Driver Code
S = "1010001";
print(minimumCost(S));
 
# This code is contributed by _saurabh_jaiswal.


C#
// C# program for the above approach
using System;
using System.Collections;
using System.Collections.Generic;
                     
public class Program
{
   
// Function to find the minimum cost
// required to swap every set bit with
// an unset bit
static int minimumCost(string s)
{
    int INF = 1000000000;
    int N = s.Length;
 
    // Stores the indices of set and
    // unset bits of the string S
    List A = new List();
    List B = new List();
 
    // Traverse the string S
    for (int i = 0; i < N; i++) {
 
        // Store the indices
        if (s[i] == '1') {
            A.Add(i);
        }
        else {
            B.Add(i);
        }
    }
 
    int n1 = A.Count;
    int n2 = B.Count;
 
    // Initialize a dp table of size
    // n1*n2
    int [,]dp = new  int[n1 + 1,n2 + 1];
 
 
    // Set unreachable states to INF
    for (int i = 1; i <= n1; i++) {
        dp[i,0] = INF;
    }
 
    // Fill the dp Table according to
    // the given recurrence relation
    for (int i = 1; i <= n1; i++) {
        for (int j = 1; j <= n2; j++) {
 
            // Update the value of
            // dp[i][j]
            dp[i,j] = Math.Min(
                dp[i,j - 1],
                dp[i - 1,j - 1]
                    + Math.Abs(A[i - 1] - B[j - 1]));
        }
    }
 
    // Return the minimum cost
    return dp[n1,n2];
}
     
    public static void Main()
    {
        string S = "1010001";
        Console.Write(minimumCost(S));
    }
}
 
// This code is contributed by rutvik_56.


Javascript


输出:
3

时间复杂度: O(K*(N – K)) 其中 K 是S中设置位的计数
辅助空间: O(K*(N – K))