有多少种方法可以使n的数字长度从0、1和2开始?

时间:2019-02-01 11:25:05

标签: c

您的数字长度为n,由3个数字组成:0,1和2:
021112201 ...

a)如果两个零不能在一起,有多少种方法可以产生这个数字?
b)如果两个零和两个不能保持在一起,有多少种方法可以产生这个数字?

我写了下面的代码来解决这个问题。有没有办法用简单的公式手动计算此任务?

#include <stdio.h>  

int main() {   
    int n; //length 
    scanf("%d", &n);
    int a[n+1][3];
    a[1][0]=a[1][1]=a[1][2];
    for (int i=2; i<=n; ++i) {
        // only for zeroes
        a[i][0] = a[i-1][0]+a[i-1][1]+a[i-1][2];
        a[i][1] = a[i-1][0]+a[i-1][2];
        a[i][2] = a[i-1][0]+a[i-1][1]+a[i-1][2];
        // for zeroes and ones
        /*
        a[i][0] = a[i-1][0]+a[i-1][1]+a[i-1][2];
        a[i][1] = a[i-1][0]+a[i-1][2];
        a[i][2] = a[i-1][0]+a[i-1][1];
        */
     }
     printf("sum: %d;", a[n][0] + a[n][1] +  a[n][2];
     return 0;

1 个答案:

答案 0 :(得分:2)

当我理解正确时,您的代码没有执行应有的操作。 只是为了确保我们正在谈论相同的问题:

length 2:
00 not ok
01, 02, 11, 12, 20, 21, 22 ok
length 3:
001,...,200 not ok
010,011,101, 201...,222 ok

您想知道标有“ ok”的数字的数量。

您可以构建一棵树,其中从根开始的每个路径都是有效数字(不包含00)。

         /       |       \
     0           1           2
    /  \       / | \       / | \
  1     2    0   1   2    0  1   2
 /|\   /|\  /|  /|\ /|\  /| /|\ /|\
 012   012  12  012 012  12 012 012

您需要计算第n级的节点数。

这就像询问Lindenmayer-System产生的单词多长时间(https://en.wikipedia.org/wiki/L-system)。 'a'代表1或2,'b'代表0

    a->baa, (when you have a 1 or 2 as first digit, you can add 0, 1, or 2)
    b->aa (when you have a 0 as first digit you can only add 1 or 2)

您从单个“ a”开始,并应用此替换规则n次。

step 0: a
step 1: b a a
step 2: aa baa baa
step 3: baa baa  aa baa baa aa baa baa

您应该看到上面树的类比。 由此您可以得到一个递归公式

length(n+1)=(length(n)+length(n-1))*2
startig with length(0)=1, length(1)=3

公式应该正确。我还没有找到一个很好的简单公式。

以下代码应计算正确的结果:

int x1 = 1, x2=3;
for(int i = 1; i < n; ++i) {
    int x = 2 * (x1 + x2);
    x1 = x2;
    x2 = x
}
// result is in x2

第二种情况下的Lindenmayer系统是:

a->ab
b->aab
stating with b

其中“ a”代表0或1,而“ b”代表2。 这种情况的公式:

length(n+1)=length(n)*2+length(n-1)
startig with length(0)=1, length(1)=3