📌  相关文章
📜  根据给定条件从给定二进制字符串中删除所有 1 的最低成本

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

根据给定条件从给定二进制字符串中删除所有 1 的最低成本

给定一个10的二进制序列。我们的任务是通过以下操作以最小成本从序列中删除所有 1。

  • 从左端移除一个 1(即移除 s[0]),它花费 1 个硬币。
  • 从右端移除一个 1(即移除 s[s.length – 1]),它花费 1 个硬币。
  • 从序列中花费 2 个硬币的任意位置删除一个 1。

返回从序列中删除所有 1 的最小成本。

例子:

方法:这个想法是使用带有滑动窗口的DP。使用数组 dp[N] ,其中 dp[i] 存储最小硬币以从索引 i 到 n-1 删除所有 1,我们只能从右侧删除。请按照以下步骤操作。

  • 从最右边的索引循环。因此,对于任何索引 i,转换如下:
    • 如果是“0”,则 dp[i]=dp[i+1]
    • 如果它是“1”,那么我们有两个选择——要么将此元素视为中间元素,然后将 2 添加到 dp[i+1] 或删除所有元素。因此,dp[i]=min(dp[i+1]+2, ni)
  • 现在,还要从左侧删除元素。所以,遍历向量。
    • 当我们到达任何索引 i 时,我们将认为我们已经从左侧删除了从 0 到 i 的所有元素。
    • 因此,我们对该索引的时间将是 i+1+dp[i+1]。
    • 因为,我们已经删除了直到 i 的所有元素,我们只需要考虑 i+1 中的元素,因此我们将 dp[i+1] 添加到我们的 i+1。
  • 最后返回最小答案

下面是代码实现:

C++
// C++ program for find the minimum cost
// to remove all 1's from the given binary string
#include 
using namespace std;
 
// Function to find minimum cost
int minimumCoin(string s)
{
    int n = s.length();
    vector dp(n, 0);
    if (s[n - 1] == '0') {
        dp[n - 1] = 0;
    }
    else {
        dp[n - 1] = 1;
    }
    for (int i = n - 2; i >= 0; i--) {
        if (s[i] == '0')
            dp[i] = dp[i + 1];
        if (s[i] == '1') {
 
            // consider current index to
            // be a middle one and remove
            dp[i] = 2 + dp[i + 1];
 
            // or remove all to the right
            dp[i] = min(dp[i], n - i);
        }
    }
 
    // now go from left to right
    int ans = dp[0];
    for (int i = 0; i < n - 1; i++) {
 
        // cost of removing all
        // from left and dp[i+1]
        ans = min(ans, i + 1 + dp[i + 1]);
    }
 
    // taking overall minimum
    ans = min(ans, n);
    return ans;
}
 
// Driver function
int main()
{
 
    string str = "1001001";
    int coins = minimumCoin(str);
    cout << coins;
    return 0;
}


Java
//Java program for find the minimum cost
// to remove all 1's from the given binary string
import java.io.*;
 
class GFG {
 
  // Function to find minimum cost
  static int minimumCoin(String s)
  {
    int n = s.length();
    int dp[] = new int[n];
    if (s.charAt(n - 1) == '0') {
      dp[n - 1] = 0;
    }
    else {
      dp[n - 1] = 1;
    }
    for (int i = n - 2; i >= 0; i--) {
      if (s.charAt(i) == '0')
        dp[i] = dp[i + 1];
      if (s.charAt(i) == '1') {
 
        // consider current index to
        // be a middle one and remove
        dp[i] = 2 + dp[i + 1];
 
        // or remove all to the right
        dp[i] = Math.min(dp[i], n - i);
      }
    }
 
    // now go from left to right
    int ans = dp[0];
    for (int i = 0; i < n - 1; i++) {
 
      // cost of removing all
      // from left and dp[i+1]
      ans = Math.min(ans, i + 1 + dp[i + 1]);
    }
 
    // taking overall minimum
    ans = Math.min(ans, n);
    return ans;
  }
 
  // Driver function
  public static void main (String[] args) {
    String str = "1001001";
    int coins = minimumCoin(str);
    System.out.println(coins);
  }
}
 
// This code is contributed by hrithikgarg03188.


Python3
# Python code for the above approach
 
# Function to find minimum cost
def minimumCoin(s):
 
    n = len(s)
    dp = [0]*n
    if (s[n - 1] == '0'):
        dp[n - 1] = 0
 
    else:
        dp[n - 1] = 1
 
    for i in range(n-2, -1, -1):
        if s[i] == '0':
            dp[i] = dp[i + 1]
        if s[i] == '1':
 
            # consider current index to
            # be a middle one and remove
            dp[i] = 2 + dp[i + 1]
 
            # or remove all to the right
            dp[i] = min(dp[i], n - i)
 
    # now go from left to right
    ans = dp[0]
    for i in range(0, n-1):
 
        # cost of removing all
        # from left and dp[i+1]
        ans = min(ans, i + 1 + dp[i + 1])
 
    # taking overall minimum
    ans = min(ans, n)
    return ans
 
# Driver function
str = "1001001"
coins = minimumCoin(str)
print(coins)
 
# This code is contributed by Potta Lokesh


C#
// C# program for find the minimum cost
// to remove all 1's from the given binary string
using System;
 
class GFG {
 
  // Function to find minimum cost
  static int minimumCoin(string s)
  {
    int n = s.Length;
    int[] dp = new int[n];
    if (s[n - 1] == '0') {
      dp[n - 1] = 0;
    }
    else {
      dp[n - 1] = 1;
    }
    for (int i = n - 2; i >= 0; i--) {
      if (s[i] == '0')
        dp[i] = dp[i + 1];
      if (s[i] == '1') {
 
        // consider current index to
        // be a middle one and remove
        dp[i] = 2 + dp[i + 1];
 
        // or remove all to the right
        dp[i] = Math.Min(dp[i], n - i);
      }
    }
 
    // now go from left to right
    int ans = dp[0];
    for (int i = 0; i < n - 1; i++) {
 
      // cost of removing all
      // from left and dp[i+1]
      ans = Math.Min(ans, i + 1 + dp[i + 1]);
    }
 
    // taking overall minimum
    ans = Math.Min(ans, n);
    return ans;
  }
 
  // Driver function
  public static void Main()
  {
    string str = "1001001";
    int coins = minimumCoin(str);
    Console.Write(coins);
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript



输出
4

时间复杂度: O(n)
空间复杂度:O(n)