简体   繁体   English

二进制字符串约简

[英]Binary String Reduction

you are given a binary string (only 0's and 1's) s of length n .你给出一个二进制串(只有0和1级的)■长度的n个
you want to convert s into an empty string by performing the following operation the least number of times.您希望通过执行以下操作最少次数将s转换为空字符串。

  • In one Operation, you can remove an alternating subsequence from s without changing the order of the remaining characters.在一个操作中,您可以从s 中删除一个交替的子序列,而无需更改剩余字符的顺序。

your task is to determine the minimum number of operations required to convert s into an empty string.您的任务是确定将 s 转换为空字符串所需的最少操作数。

Note:笔记:

An alternating subsequence of a string s is defined as follows字符串 s 的交替子序列定义如下

  • Any subsequence of length 1任何长度为 1 的子序列
  • if length greater than 1, and no two consecutive elements being equal.如果长度大于 1,并且没有两个连续元素相等。 For Example, '0101', '101', '0' are alternating sequences, while '100' and '01011' are not.例如,“0101”、“101”、“0”是交替序列,而“100”和“01011”则不是。

Constraints:约束:

1 <= T <= 10
1 <= n <= 10^6

Sample Input:样本输入:

1
10
0100100111

Sample Output:示例输出:

3

Explanation:解释:

remove subsequence "010101" from " 01 0 01 0 01 11" to make it "0011"从“ 01 0 01 0 01 11”中删除子序列“010101”使其成为“0011”

remove subsequence "01" from " 0 01 1 " to make it "01"从“ 0 01 1 ”中删除子序列“ 01”以使其成为“ 01”

finally, remove subsequence "01" from " 01 " to make it "" (empty binary string)最后,从“ 01 ”中删除子序列“ 01”以使其成为“”(空二进制字符串)

Imagine that for some string x , you know that you can erase it using m operations that end in '0' and n operations that end in '1', for a total of ( m+n ) operations.想象一下,对于某个字符串x ,您知道可以使用m 个以“0”结尾的操作和n 个以“1”结尾的操作来擦除它,总共 ( m+n ) 个操作。 We will write this (m,n).我们将写这个 (m,n)。 This is not necessarily the best result, but it is a result.这不一定是最好的结果,但它是一个结果。

Now, what do you know about the string x0 ?现在,您对字符串x0了解多少?

If n>1, then you could add a zero to one of those 1-ending operations, turning it into a zero-ending operation, so you could clear x0 in (m+1,n-1) operations.如果 n>1,那么您可以向那些以 1 结尾的操作之一添加零,将其转换为以零结尾的操作,因此您可以清除 (m+1,n-1) 操作中的x0

And of course you could always just add a new 0-ending operation so you could clear x0 in (m+1,n) operations.当然,您总是可以添加一个新的0 结束操作,以便您可以清除 (m+1,n) 操作中的x0

Similarly, you could clear x1 in (m,n+1) operations, or (m-1,n+1) if m>0.同样,您可以在 (m,n+1) 操作中清除x1 ,如果 m>0,则可以清除 (m-1,n+1)。

Obviously there's only one way to clear the empty string, and that's with (0,0) operations, so working from the start to the end, you can calculate all of the various (m,n) possibilities to clear each prefix until you get to the end, and then the one with the smallest sum is your answer.显然只有一种方法可以清除空字符串,那就是 (0,0) 操作,所以从头到尾工作,您可以计算所有各种 (m,n) 可能性来清除每个前缀,直到您得到到最后,然后总和最小的那个就是你的答案。 That would be an O(n 2 ) algorithm.那将是一个 O(n 2 ) 算法。

But, there is no case in which choosing (m+1,n) instead of (m+1,n-1) will enable you to use fewer operations overall.但是,有其中任何情况下,选择(M + 1,N)代替(M + 1,N-1),使您能够全面使用较少的操作。 Similarly, there is no case in which choosing (m, n+1) is better than (m-1,n+1).类似地,也不存在选择 (m, n+1) 优于 (m-1,n+1) 的情况。

So, instead of worrying about both possible choices at each position, we can make the single best choice deterministically, depending on whether the next character is 0 or 1:因此,与其担心每个位置的两种可能选择,我们可以确定性地做出单个最佳选择,具体取决于下一个字符是 0 还是 1:

Starting with x="" and (m,n) = (0,0):以 x="" 和 (m,n) = (0,0) 开头:

  • When the next char is 0, then x <- x+"0" and (m,n) <- (m+1,max(n-1,0))当下一个字符为 0 时,则 x <- x+"0" 和 (m,n) <- (m+1,max(n-1,0))

  • When the next char is 1, then x <- x+"1" and (m,n) <- (max(m-1,0),n+1)当下一个字符为 1 时,则 x <- x+"1" 和 (m,n) <- (max(m-1,0),n+1)

When you get to the end of the string, m+n is the fewest number of operations that can clear it.当您到达字符串的末尾时,m+n 是可以清除它的最少操作数。

Or, in pseudocode:或者,在伪代码中:

m = 0; n = 0;
for (char in string) {
    if (char == 0') {
        m = m+1;
        n = max(n-1,0);
    } else {
        m = max(m-1,0);
        n = n+1;
    }
}
return m+n;

Easy peasy.十分简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM