扎卡里:
假设你得到了这个重复:
r(n) = 2*r(n-2) + r(n-1); r(1) = r(2) = 1
这实际上是主定理的形式吗?如果是这样,用语言来说,它在说什么?
我认为你的递归关系所说的是,对于以“n”为参数的“r”函数(代表你输入的数据集的总数),无论你在数据集的第 n 个位置得到什么是第 n-1 个位置的输出加上第 n-2 个位置的结果的两倍,没有进行非递归工作。当您尝试解决递归关系时,您正在尝试以不涉及递归的方式表达它。
但是,我认为这不是主定理方法的正确形式。您的陈述是“具有恒定系数的二阶线性递推关系”。显然,根据我的旧离散数学教科书,这是解决递归关系所需的形式。
这是他们提供的表格:
r(n) = a*r(n-1) + b*r(n-2) + f(n)
因为'a'和'b'是一些常数,f(n)是n的一些函数。在您的陈述中,a = 1、b = 2 和 f(n) = 0。只要 f(n) 等于零,递归关系就称为“同质”。所以,你的表达是同质的。
我不认为你可以使用主方法定理来解决同质递归关系,因为 f(n) = 0。主方法定理的任何情况都不允许这样做,因为任何事物的 n-to-the-power-of-anything 都可以'不等于零。我可能是错的,因为我不是这方面的专家,但我不认为使用主方法解决同质递归关系是可能的。
我认为解决齐次递推关系的方法是通过 5 个步骤:
1) 形成特征方程,其形式为:
x^k - c[1]*x^k-1 - c[2]*x^k-2 - ... - c[k-1]*x - c[k] = 0
如果您的齐次递归关系中只有 2 个递归实例,那么您只需将方程更改为二次方程,其中
x^2 - a*x - b = 0
这是因为形式的递归关系
r(n) = a*r(n-1) + b*r(n-2)
可以重写为
r(n) - a*r(n-1) - b*r(n-2) = 0
2)将递推关系改写为特征方程后,接下来找到特征方程的根(x [1]和x [2])。
3) 有了您的根,您的解决方案现在将是以下两种形式之一:
if x[1]!=x[2]
c[1]*x[1]^n + c[2]*x[2]^n
else
c[1]*x[1]^n + n*c[2]*x[2]^n
当 n>2 时。4) 使用新形式的递归解决方案,您可以使用初始条件(r(1) 和 r(2))找到 c[1] 和 c[2]
以您的示例为例,这就是我们得到的:
1) r(n) = 1*r(n-1) + 2*r(n-2) => x^2 - x - 2 = 0
2) 求解 x
x = (-1 +- sqrt(-1^2 - 4(1)(-2)))/2(1)
x[1] = ((-1 + 3)/2) = 1
x[2] = ((-1 - 3)/2) = -2
3) 由于 x[1] != x[2],您的解决方案具有以下形式:
c[1](x[1])^n + c[2](x[2])^n
4) 现在,使用您的初始条件找到两个常数 c[1] 和 c[2]:
c[1](1)^1 + c[2](-2)^1 = 1
c[1](1)^2 + c[2](-2)^2 = 1
老实说,我不确定在这种情况下你的常数是什么,我在这一点上停了下来。我猜你必须插入数字,直到你以某种方式得到 c[1] 和 c[2] 的值,这两个值都满足这两个表达式。要么对矩阵 C 执行行缩减,其中 C 等于:
[ 1 1 | 1 ]
[ 1 2 | 1 ]
扎卡里:
以最佳方式描述以下程序片段中加法运算次数的递归(当使用 l == 1 和 r == n 调用时)
int example(A, int l, int r) {
if (l == r)
return 2;
return (A[l] + example(A, l+1, r);
}
这是当 r>l 时给定代码的时间复杂度值:
int example(A, int l, int r) { => T(r) = 0
if (l == r) => T(r) = 1
return 2; => T(r) = 1
return (A[l] + example(A, l+1, r); => T(r) = 1 + T(r-(l+1))
}
Total: T(r) = 3 + T(r-(l+1))
否则,当 r==l 时 T(r) = 2,因为 if 语句和 return 都需要每次执行 1 步。