如何找出所有满足分值和为x的二进制字符串?(1计2分,0计1分)
嘿,这个问题我刚好琢磨过!咱们一步步来拆解怎么高效枚举所有符合条件的二进制字符串,顺便也聊聊为啥解的数量是斐波那契(x+1)~
问题分析与枚举方法
首先咱们先把问题转化成数学语言:设二进制字符串里有k个'1',m个'0',根据分值规则,满足2k + m = x。而字符串总长度是k + m = x - k(因为m = x - 2k)。所以k的取值范围是从0到x//2(毕竟2k不能超过x)。
比如你举的x=5的例子:
k=0时,m=5,对应字符串00000k=1时,m=3,总长度4,所有含1个'1'的4位二进制串:1000、0100、0010、0001k=2时,m=1,总长度3,所有含2个'1'的3位二进制串:110、101、011
加起来正好8个,和斐波那契(6)=8对应上了。
方法一:按'1'的数量分类生成排列
这个方法的核心是先确定每个可能的k值,然后生成所有含k个'1'的对应长度的二进制串。本质是生成组合数对应的位置排列,再构造字符串。
代码示例(Python)
import itertools def generate_binary_strings(x): result = [] max_k = x // 2 for k in range(max_k + 1): m = x - 2 * k total_length = k + m # 生成所有在total_length个位置中选k个放'1'的组合 for positions in itertools.combinations(range(total_length), k): # 初始化全0字符串 s = ['0'] * total_length # 把选中的位置改成'1' for pos in positions: s[pos] = '1' result.append(''.join(s)) return result # 测试x=5的情况 print(generate_binary_strings(5))
运行这段代码就能得到你例子里的所有字符串,而且是按字符串长度从长到短排列的。
方法二:递归/回溯生成所有可能
如果不想搞组合数,递归回溯的思路更直观:每次给当前字符串加'0'或'1',同时减去对应的分值(加'0'减1,加'1'减2),当剩余分值为0时就记录这个字符串;如果剩余分值小于0就停止回溯。
代码示例(Python)
def generate_binary_strings_recursive(x): result = [] def backtrack(remaining_score, current_str): if remaining_score == 0: result.append(current_str) return if remaining_score < 0: return # 尝试加'0',剩余分值减1 backtrack(remaining_score - 1, current_str + '0') # 尝试加'1',剩余分值减2 backtrack(remaining_score - 2, current_str + '1') backtrack(x, "") return result # 测试x=5的情况 print(generate_binary_strings_recursive(5))
这个方法生成的字符串顺序和分类法不同,但所有符合条件的串都会被枚举出来,逻辑上更贴近“穷举所有可能”的思路。
为啥解的数量是斐波那契(x+1)?
咱们用递推的思路看:设f(x)是分值和为x的字符串数量。
- 如果最后一个字符是'0',那前面的字符串分值和是
x-1,数量是f(x-1) - 如果最后一个字符是'1',那前面的字符串分值和是
x-2,数量是f(x-2)
所以递推公式是f(x) = f(x-1) + f(x-2)
初始条件:
f(0)=1(分值和为0时只有空字符串)f(1)=1(只有"0"这一个串)
对应斐波那契数列的话,如果斐波那契数列定义为F(1)=1, F(2)=1, F(3)=2, F(4)=3, F(5)=5, F(6)=8,那f(x)=F(x+1),正好和你说的一致~
内容的提问来源于stack exchange,提问作者Sentpro
相关产品推荐
相关产品推荐

