📅  最后修改于: 2023-12-03 14:49:19.400000             🧑  作者: Mango
Stern 的双原子级数是一种非常有趣的数列,它的定义如下:
根据这个定义,我们可以得到前几项:
0, 1, 1, 2, 1, 3, 2, 3, 1, 4, 3, 5, 2, 5, 3, 4, 1, 5, 4, 7, 3, 8, 5, 7, 2, 7, 5, 8, 3, 7, 4, 5, 1, 6, 5, 9, 4, 11, 7, 10, 3, 11, 8, 13, 5, 12, 7, 9, 2, 9, 7, 12, 5, 13, 8, 11, 3, 10, 7, 11, 4
很容易发现,这个数列中有许多重复的项,因此我们可以采用动态规划的思路来解决这个问题。
具体做法是:用一个数组 $a
存储第 $i$ 位的值,用另外一个数组 $b
存储第 $i$ 位前面有多少个不同的值。初始时,$a_0 = 0, a_1 = 1, b_0 = 0, b_1 = 1$。然后我们从 $i = 2$ 开始,根据上述的递推关系式,计算出 $a_i$,然后比较 $a_i$ 与前面的所有 $a_j (j < i)$ 是否相等,如果相等,则 $b_i = b_{i-1}$,否则 $b_i = b_{i-1} + 1$。
最后,当 $i > n$ 时,直接返回 $a_n$ 即可。
代码如下:
/**
* @param int $n
* @return int
*/
function sternSequence($n)
{
$a = [0, 1];
$b = [0, 1];
for ($i = 2; $i <= $n; ++$i) {
$a[$i] = ($i % 2 == 0) ? $a[$i/2] : $a[($i-1)/2] + $a[($i+1)/2];
$b[$i] = $b[$i-1] + (($a[$i] == $a[$i-1]) ? 0 : 1);
}
return $a[$n];
}
该函数的时间复杂度为 $O(n)$,空间复杂度为 $O(n)$,可以在很短的时间内计算出数列中任意一项的值。
以上是对 Stern 的双原子级数的介绍和解法,希望能对大家有所帮助。