📌  相关文章
📜  通过翻转给定二进制字符串中的最多K个位来最大化分配的权重之和

📅  最后修改于: 2021-05-06 21:44:30             🧑  作者: Mango

给定长度为N且整数K的二进制字符串str ,任务是找到分配的权重的最大可能和,该权重可以通过翻转给定二进制字符串中的最多K个位来获得。分配给该字符串字符的权重如下:

  • 如果字符为“ 0” ,则权重为0
  • 如果一个字符为‘1’并且其前面的字符也是‘1’ ,则权重为2
  • 如果一个字符为‘1’并且在其之前没有字符或该字符之前的字符为‘0’ ,则权重为1

例子:

做法:字符“1”“1”之后出现的重量是所有字符中最伟大的,所以最大限度的总和,尽量创造尽可能多这样的1秒。可以将要翻转为10的段划分优先级,如下所示:

  • 第一优先级:翻转两个1之间封闭的所有0 ,这将使形式10…01的段的权重增加(2 *(封闭的0的数量)+ 1)。如果x大于或等于封闭的0数,否则为2 *(封闭的0数)。
  • 第二优先度”1秒的第一次出现之前的字符串中的字符串的开头翻转为0,这将增加形式0的链段的重由2 *(翻转数的0的)01。
  • 第三优先级:在字符串的最后一次出现1之后,在字符串末尾翻转0 ,这将使形式10…0的段的权重增加2 *(翻转的0的数量)。

按照上述优先级翻转给定字符串的字符,以使权重最大化,然后在最多翻转K次之后找到所得字符串的权重。

以下是此方法的实现:

C++
// C++ program of the above approach
#include 
using namespace std;
 
// Function to find maximum sum of
// weights of binary string after
// at most K flips
int findMax(string s, int n, int k)
{
    int ans = 0;
 
    // Stores lengths of substrings
    // of the form 1..00..1s
    int l = 0;
 
    // Stores the index of last 1
    // encountered in the string
    int ind = -1;
 
    // Stores the index of first 1
    // encountered
    int indf = -1;
 
    // Stores lengths of all substrings
    // having of 0s enclosed by 1s
    // at both ends
    multiset ls;
 
    // Traverse the string
    for (int i = 0; i < n; i++) {
        // If character is 0
        if (s[i] == '0')
            l++;
 
        // If character is 1
        // First Priority
        else if (s[i] == '1'
                 && l > 0 && ans != 0) {
            ls.insert(l);
            l = 0;
        }
 
        // Second Priority
        if (s[i] == '1') {
            ind = i;
            l = 0;
            if (indf == -1)
                indf = i;
 
            // Add according to the
            // first priority
            if (i > 0 && s[i - 1] == '1')
                ans += 2;
            else
                ans += 1;
        }
    }
 
    // Stores length of the shortest
    // substring of 0s
    int curr;
 
    // Convert shortest substrings
    // of 0s to 1s
    while (k > 0 && !ls.empty()) {
        curr = *ls.begin();
 
        // Add according to the
        // first priority
        if (k >= curr) {
            ans += (2 * curr + 1);
            k -= curr;
        }
 
        // Add according to the
        // third priority
        else {
            ans += (2 * k);
            k = 0;
        }
        ls.erase(ls.begin());
    }
 
    // If more 0s can be made into 1,
    // then check for 0s at ends
    if (k > 0) {
        // Update the ans
        ans += (2 * min(k,
                        n - (ind + 1))
                - 1);
        k -= min(k, n - (ind + 1));
 
        if (ind > -1)
            ans++;
    }
 
    // If K is non-zero, then flip 0s
    // at the beginning
    if (k > 0) {
        ans += (min(indf, k) * 2 - 1);
 
        if (indf > -1)
            ans++;
    }
 
    // Return the final weights
    return ans;
}
 
// Driver Code
int main()
{
    // Given string str
    string str = "1110000101";
 
    int N = str.length();
 
    // Given K flips
    int K = 3;
 
    // Function Call
    cout << findMax(str, N, K);
 
    return 0;
}


Python3
# Python 3 program of the above approach
 
# Function to find maximum sum of
# weights of binary string after
# at most K flips
def findMax( s, n, k):
 
    ans = 0;
 
    # Stores lengths of substrings
    # of the form 1..00..1s
    l = 0;
 
    # Stores the index of last 1
    # encountered in the string
    ind = -1;
 
    # Stores the index of first 1
    # encountered
    indf = -1;
 
    # Stores lengths of all substrings
    # having of 0s enclosed by 1s
    # at both ends
    ls = set([])
 
    # Traverse the string
    for i in range(n):
        # If character is 0
        if (s[i] == '0'):
            l+=1
 
        # If character is 1
        # First Priority
        elif (s[i] == '1'
                 and l > 0 and ans != 0):
            ls.add(l);
            l = 0;
 
        # Second Priority
        if (s[i] == '1') :
            ind = i;
            l = 0;
            if (indf == -1):
                indf = i;
 
            # Add according to the
            # first priority
            if (i > 0 and s[i - 1] == '1'):
                ans += 2;
            else:
                ans += 1;
 
    # Stores length of the shortest
    # substring of 0s
    curr = 0
 
    # Convert shortest substrings
    # of 0s to 1s
    while (k > 0 and len(ls)!=0):
        for i in ls:
          curr = i
          break
 
        # Add according to the
        # first priority
        if (k >= curr):
            ans += (2 * curr + 1);
            k -= curr;
 
        # Add according to the
        # third priority
        else :
            ans += (2 * k);
            k = 0;
        
        ls.remove(curr);
     
    # If more 0s can be made into 1,
    # then check for 0s at ends
    if (k > 0) :
        # Update the ans
        ans += (2 * min(k,
                        n - (ind + 1))
                - 1);
        k -= min(k, n - (ind + 1));
 
        if (ind > -1):
            ans+=1
 
    # If K is non-zero, then flip 0s
    # at the beginning
    if (k > 0):
        ans += (min(indf, k) * 2 - 1);
 
        if (indf > -1):
            ans+=1
    
    # Return the final weights
    return ans
 
# Driver Code
if __name__ == "__main__":
   
    # Given string str
    s = "1110000101";
 
    N = len(s)
 
    # Given K flips
    K = 3;
 
    # Function Call
    print(findMax(s, N, K));
 
    # This code is contributed by chitranayal


输出:
14

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