根据给定条件确定最多"1"的子序列的最小步骤

data structurec++server side programmingprogramming

本文的目标是实现一个程序,根据给定条件,找到确定最多"1"的子序列的最小步骤。

众所周知,一个以空值结尾的包含字符的一维数组可以用来定义字符串。

给定一个长度为K的字符串Str,其中K始终为偶数,包含字符"0"、"1"和"?"。将字符串分成两个独立的字符串,分别称为Str1和Str2,每个字符串都包含Str偶数和奇数处的字符。目标是确定预测Str1和Str2中哪个字符串包含最多"1"所需的最少步骤。一步为Str1或Str2选择一个字符。当字符为零时,选择"0";当字符为一时,选择"1";当字符为一或零时,选择"?"。

问题描述

编写一个程序,根据给定条件,找出包含最多 1 的子序列的最小步骤。

示例 1

输入:Str = "?10?0?"
输出:4

解释

  • 步骤 1 − 这里 Str[0] 为 "?

因此,选择"0"作为 Str1 的字符。
这意味着 Str1="0″,Str2="″。
  • 步骤 2 − 这里 Str[1] 为 "1"

选择"1"作为 Str2 的字符。
这意味着 Str1="0″,Str2="1″。
  • 步骤 3 − 此处 Str[2] 为"0"

选择"0"作为 Str1 的字符。
这意味着 Str1="00″,Str2="1″。
  • 步骤 4 − 此处 Str[3] 为"?"

选择"1"作为 Str2 的字符。
这意味着 Str1="00″,Str2="11″。

无论剩余索引选择什么数字,Str2 在步骤 4 之后都会包含更多 1。

示例 2

输入:Str = "1?0??0110"
输出:4

解释

  • 步骤 1 − 这里 Str[0] 为 "1"

因此,选择 "1" 作为 Str1 的字符。
这意味着 Str1="1″,Str2="″。
  • 步骤 2 − 这里 Str[1] 为 "?

选择"1"作为 Str2 的字符。
这意味着 Str1="1″,Str2="1″。
  • 步骤 3 − 这里 Str[2] 为 "0"

选择"0"作为 Str1 的字符。
这意味着 Str1="10″,Str2="1″。
  • 步骤 4 − 此处 Str[3] 为 "?

选择"1"作为 Str2 的字符。
这意味着 Str1="10″,Str2="11″。
  • 步骤 5 − 此处 Str[4] 为 "?

选择"0"作为 Str1 的字符。
这意味着 Str1="100″,Str2="11″。
  • 步骤 6 − 此处 Str[5] 为"0"

选择"0"作为 Str2 的字符。
这意味着 Str1="100″,Str2="111″。
  • 步骤 7 − 此处 Str[6] 为"1"

选择"1"作为 Str1 的字符。
这意味着 Str1="1001″,Str2="111″。

无论剩余索引选择什么数字,Str2 在步骤 7 之后都会有更多 1。

解决方法

为了在给定条件下找到确定最多 1 的子序列的最小步骤,我们采用以下方法。

下面给出了解决这个问题的方法,以及在给定条件下找到确定最多 1 的子序列的最小步骤。

目标是递归地解决问题,并在考虑所有替代方案后找到解决方案。

"递归"一词只不过是一个函数调用自身的过程,无论是直接调用(即没有中介)还是间接调用。这个等效函数被认为是递归函数。递归算法还可以相对轻松地解决各种问题。

算法

根据以下给定条件,找到确定最多包含 1 的子序列的最小步骤的算法

  • 步骤 1 - 开始

  • 步骤 2 - 定义递归函数。

  • 步骤 3 - 定义字符串 Str、整数 i、整数 count1 和 count2,分别用于在 Str1 和 Str2 中存储从 i 到 1 的个数。

  • 步骤 4 - 定义整数 n1 和 n2,用于存储 Str1 和 Str2 中的可用位置。

  • 步骤 5 - 如果 i等于 m,则 Str1 和 Str2 都已完全填充,现在可以确定地预测答案。因此返回 0。

  • 步骤 6 - 如果 count1 超过 n2 与 count2 的乘积,则返回 0,因为即使 Str2 中的所有 1 都被选中,Str1 中的 1 仍然比 Str2 多。

  • 出于上述原因,如果 count2 超过 n1 与 count1 的乘积,则返回 0。

  • 步骤 7 - 在测试基本实例后,验证 i 是等于偶数还是奇数。如果 i 是偶数,Str1 将选择该索引;如果不是,则返回 Str2。

  • 由于填充后字符串中可访问位置的数量将减少一个位置,因此根据当前正在填充的字符串减少 n1 或 n2。

  • 步骤 8 − 假设当前字符为 '?',即 s[i] = '? ' 然后执行两次递归调用,一次选择"1",一次取出"0",并将 1 添加到两者中,返回两者中最小的值。

  • 否则,进行一次递归调用,然后将结果加 1 得到答案。

    此查询的响应将由最后一次递归调用提供。

  • 步骤 8 - 停止

示例:C++ 程序

以下是上述算法的 C 程序实现,该算法根据给定条件,找到确定最多包含 1 的子序列的最小步骤。

// 上述算法的 C++ 程序
#include <bits/stdc++.h>
using namespace std;

// 该函数通过组合两个字符串来找到递归所需的最少步骤数
int minimumSteps(string& Str, int cnt1, int cnt2,int n1, int n2, int m,int i){

    // 检查当前指针是否到达 //末尾
    if (i == m) {
        return 0;
    }
    
    // 此条件指示,无论剩余的索引选择哪个数字,一个字符串的"1"数都比另一个字符串多
   if (cnt1 > (n2 + cnt2)
         || cnt2 > (n1 + cnt1)) {
      return 0;
   }
   int ch1 = 0;
   int ch2 = 0;
    
   // 如果 i 为偶数,则选择 Str 的字符
   if (i % 2 == 0) {
      if (Str[i] == '?') {
         return min( 1 + minimumSteps(Str, i + 1,  cnt1 + 1, cnt2, n1 - 1, n2, m), 1 + minimumSteps( Str, i + 1, cnt1, cnt2, n1 - 1, n2, m));
      } else if (Str[i] == '1') {
         ch1 = 1 + minimumSteps(Str, i + 1, cnt1 + 1, cnt2, n1 - 1, n2, m);
         return ch1;
      } else {
         ch2 = 1 + minimumSteps(Str, i + 1, cnt1, cnt2, n1 - 1, n2, m);
         return ch2;
      }
   }
   else {
      if (Str[i] == '?') {
         return min(1 + minimumSteps(Str, i + 1, cnt1, cnt2 + 1, n1, n2 - 1, m),1 + minimumSteps(Str, i + 1,cnt1, cnt2, n1, n2 - 1, m));
      } else if (Str[i] == '1') {
         ch1 = 1+ minimumSteps(Str, i + 1, cnt1, cnt2 + 1, n1, n2 - 1, m);
         return ch1;
      } else {
         ch2 = 1+ minimumSteps( Str, i + 1, cnt1, cnt2, n1, n2 - 1, m);
         return ch2;
      }
   }
}
int main(){
   string str = "?10?0?01";
   int M = str.size();
   cout << minimumSteps(str, 0, 0, 0, M / 2, M / 2, M);
   return 0;
}

输出

1

结论

同样,我们可以根据给定条件,找到确定最多 1 的子序列的最小步骤

本文解决了根据给定条件,获取确定最多 1 的子序列的最小步骤这一难题。

本文提供了 C++ 编程代码以及根据给定条件,找到最多 1 的子序列的最小步骤的算法。


相关文章