Zachary:
假设你得到了这个递归式:
r(n) = 2*r(n-2) + r(n-1); r(1) = r(2)
= 1
这是否符合主定理的形式?如果是,用简单易懂的语言说明它的含义。
我认为你的递归关系所表达的意思是,对于一个以“r”为函数、以“n”为参数的函数(表示输入数据集的总数),在第n个位置得到的任何结果都是n-1位置的输出加上两倍n-2位置的结果,而没有进行非递归工作。当你试图解决递归关系时,你要尝试以不涉及递归的方式来表达它。
但是,我认为这并不符合主定理方法的正确形式。你的陈述是一个“具有常数系数的二阶线性递归关系”。根据我旧的离散数学教科书的说法,这是你需要拥有的形式,以便解决递归关系。
这里是他们给出的形式:
r(n) = a*r(n-1) + b*r(n-2) + f(n)
对于一些常量'a'和'b',以及函数f(n),当f(n)等于0时,递归关系被称为“齐次”的。在您的语句中,a=1,b=2,f(n)=0。因此,您的表达式是齐次的。
我认为您无法使用主方法定理解决齐次递归关系,因为f(n) = 0。主方法定理中的任何情况都不允许这种情况发生,因为n的任何幂都不能等于0。虽然我不是专家,但我认为无法使用主方法解决齐次递归关系。
我认为解决齐次递归关系的方法是按照以下5个步骤进行:
1)形成特征方程,其形式如下:
x^k - c[1]*x^k-1 - c[2]*x^k-2 - ... - c[k-1]*x - c[k] = 0
如果你的同次递归关系中只有两个递归实例,那么你只需要将方程改为二次方程,其中
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的情况,你可以使用新形式的递归解法,使用初始条件(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步。