您的数字长度为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;
答案 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