问题是字母表可以组成多少个长度为n的字符串。
条件是:
字母可以在字符串中重复
只有字母表中与字母相邻的字母才能在字符串中相邻放置。例如,如果n=4,字符串可以是d、abab、b、wxyz、xwxw等等。它们不能是e,cdeg,aaaa,因为字母表中只有相邻的字母可以放在一起。
我有n的答案,当:
如果n=3,答案是98
如果n=4,答案是192
如果n=8,答案是2896
如果n=15,答案是342840
如果n=30,答案是9841989098
如果n=40,答案是9329564680878
当n=50时,我需要找到答案。我做的算法在10秒内直到30秒都能得到正确的答案。然而,30岁以后,我认为由于我的算法的递归性质,它一直在运行,我还没有得到答案。
以下是我的java代码:
class Alphabet {
public int n;
public long counter = 0;
public static void main(String[] args) {
Alphabet a = new Alphabet(15);
a.run();
}
public Alphabet(int n) {
this.n = n;
}
public void run() {
for (int i = 0; i < 13; i++) {
this.attach(i, 1);
}
System.out.println(this.counter * 2);
}
public boolean attach(int letter, int length) {
if (length == this.n) {
this.counter++;
return true;
}
if (letter == 0) {
this.attach(1, length + 1);
return true;
}
if (letter == 25) {
this.attach(24, length + 1);
return true;
}
this.attach(letter - 1, length + 1);
this.attach(letter + 1, length + 1);
return true;
}
}
有没有更有效的方法得到答案?
2条答案
按热度按时间atmip9wb1#
对于每个字母,计算以该字母结尾的长度为1的字符串数。对于所有字母,这是1。
如果你知道以每个字母结尾的n个字母的字符串的数目,那么计算以每个字母结尾的n+1个字母字符串的#就很容易了。根据你的规则,这需要o(字母表大小)时间。反复这样做直到你得到n=n。那就把所有信的数目加起来,你就完了。
sirbozc52#
如果
x[i][j]
是具有j
以字母开头的字母i
(从0开始编号),然后x[i][j]
满足这些递推关系:这为您提供了一种动态编程风格的方法来解决问题(这里是python,因为它使算法更清晰,但将其转换为java没有根本的困难):
这是一个o(n)(算术运算)解。通过计算26x26矩阵的n次方,可以用o(logn)算术运算来求解它。
让
A
成为矩阵a[i][j]
为了i
,j
=0..25,其中a[i][j] = 1
如果|i-j]=1
否则为0。然后:
(这只是矩阵形式的递推关系)。
然后:
由于矩阵的幂可以通过o(logn)算术运算(通过平方乘幂)来计算,所以once可以计算出最终的幂
x[][n]
o(logn)时间内的向量。这在实践中并没有太大的帮助,因为数字变得很大,但是如果您需要计算一些k的结果mod k,那么这是一个很好的方法。