Algorithm 如何计算设置了k位且存在c位值变化的大小为n的位序列的数量?

Algorithm 如何计算设置了k位且存在c位值变化的大小为n的位序列的数量?,algorithm,math,combinatorics,bits,computation,Algorithm,Math,Combinatorics,Bits,Computation,我们知道,用k个比特集计算n个长度的比特序列的数目等于C(n,k)=n/(k!(n-k)!)* 但我最近问自己,一旦设置了另一个条件:比特值的数量发生变化,你怎么能考虑这个问题。例如,对于n=4和k=2,我们有6个解决方案: 1-0011 2-0101 3-0110 4-1001 5-1010 6-1100 现在假设我们只想得到位值有两个变化的序列。现在只有两种解决方案: 1-0110(从0开始,更改为1,之后更改为0)。 2-1001(从1开始,更改为0,之后更改为1) 如何快速计算解决方案的

我们知道,用k个比特集计算n个长度的比特序列的数目等于C(n,k)=n/(k!(n-k)!)*

但我最近问自己,一旦设置了另一个条件:比特值的数量发生变化,你怎么能考虑这个问题。例如,对于n=4和k=2,我们有6个解决方案:

1-0011

2-0101

3-0110

4-1001

5-1010

6-1100

现在假设我们只想得到位值有两个变化的序列。现在只有两种解决方案:

1-0110(从0开始,更改为1,之后更改为0)。 2-1001(从1开始,更改为0,之后更改为1)

如何快速计算解决方案的数量(无需生成每个组合和计数)?我认为一个人可以把最初的一点算作一个改变,而不会对答案做太多的改变,所以请随意去做

额外问题:给定一个具有k位集和c位数变化的组合,用相同数量的k位集和c位数变化生成下一个组合的最快方法是什么?

这是一个问题。从交替的
0
s和
1
s序列开始,进行所需的位数更改,然后将剩余的
0
s和
1
s放入URN

示例:
n=20
k=8
c=4

考虑双串从
0
开始的情况。从
(c+1)
交替位开始,以获得
c
更改:

01010
此时,您仍然需要放置9
0
s和6
1
s。让我们先放置
0
s。在不添加任何位更改的情况下,我们可以用多少种方式放置剩余的9个
0
s?有3个“骨灰盒”用于放置“球”(
0
s):

(9+3-1)选择3种方法将9个球放入3个骨灰盒中

放置
0
s后,我们还需要放置
1
s。通过类似的推理,我们有6个球(
1
s)放置在2个骨灰盒中,可以通过
(6+2-1)选择2种方式来完成

由于
0
s和
1
s的排列是独立的,因此我们将结果相乘:假设从
0开始,长度为20位的字符串有4位更改,则有
((9+3-1)选择3)*((6+2-1)选择2)
方式


您仍然需要添加剩余的情况(从
1
开始,因此第一步的结果是
10101
),这可以用完全相同的方法解决。

假设我们有一行
n
不可区分的对象,比如红色的球。有多少种方法可以将它们划分为
k
非空组?这很容易,对吧?第一个组从第一个对象开始,其他每个组都必须从不同的对象开始。因此,我们可以通过选择第一个对象和
n-1
剩余对象的
k-1
来构造一个分区,这可以通过
C(n-1,k-1)
不同的方式来实现

现在假设我们有另一行
m
不可区分的对象,比如蓝球,我们想把它们分成
j
组。但这是完全相同的问题,解决方案必须是
C(m-1,j-1)

好,现在假设我们要构造一行对象,其中
n
为红色,
m
为蓝色,其中总共有
c
组在红色和蓝色之间交替。现在,有两种可能性:

  • 这一排将以一个红色的球开始。如果
    c
    为偶数,则将有
    c/2
    红色组与
    c/2
    蓝色组交错。如果
    c
    为奇数,则红色组将比蓝色组多出一个,因此将有
    ceil(c/2)
    红色组和
    地板(c/2)
    蓝色组。(如果
    c
    是偶数,那么
    floor(c/2)
    ceil(c/2)
    都是
    c/2
    。因此我们可以在这两种情况下使用floor和ceil公式。)

    在任何情况下,我们都可以将红色的球分成组,将蓝色的球单独分成组,然后将它们交错。因此有
    C(n-1,celi(C/2)-1)×C(m-1,floor(C/2)-1)
    可能的安排

  • 这一排将以一个蓝色的球开始。完全相同的分析适用,除了
    n
    m
    相反

  • 因此,安排的总数为:

    C(n - 1, ceil(c/2) - 1) × C(m - 1, floor(c/2) - 1) +
    C(n - 1, floor(c/2) - 1) × C(m - 1, ceil(c/2) - 1)
    

    这只是对你的问题的重写,它有
    k
    个1和
    n-k
    个0,有
    c-1
    个转变(这导致
    c
    组)。我将把剩下的代数步骤留给读者(以及奇数组计数的简化)。

    通过两位更改,最小序列是:101和010。然后是分配多余的1和0的问题。例如,以n=10k=4c=2为例。从101开始,有两个多余的1和五个多余的0。只有一个地方可以放0。多余的1可以以三种不同的方式放置:开始时为零,结束时为二,或一加一,或开始时为二,结束时为一。所以从101开始只有三种可能性:10000001111110000001111000000001。这不是一个真正的编程问题,不是吗?这正是我经过思考直到现在才发展出来的。对于奇数c,有没有比2*c(n-1,c/2-1)*c(m-1,c/2-1)更好的进一步简化方法?@eduard:首先计算较小的二项式,这样可以避免重复两次相同的乘法
    C(n - 1, ceil(c/2) - 1) × C(m - 1, floor(c/2) - 1) +
    C(n - 1, floor(c/2) - 1) × C(m - 1, ceil(c/2) - 1)