我应该如何在没有反复试验的情况下解决这个递归

How should I go about solving this recursion without trial and error

本文关键字:情况下 解决 递归 复试 我应该      更新时间:2023-10-16
int sum_down(int x)
{
    if (x >= 0)
    {
        x = x - 1;
        int y = x + sum_down(x);
        return y + sum_down(x);
    }
    else
    {
        return 1;
    }
}

参数 x 的最小整数值是多少,以便返回值大于 1.000.000 ?

现在我只是通过反复试验来做,因为这个问题是通过纸质格式提出的。我认为我没有足够的时间来反复试验。问题是,你们如何快速想象这个问题,以便可以轻松解决。谢谢大家,我是编程新手,所以提前感谢!

递归逻辑:

x = x - 1;
int y = x + sum_down(x);
return y + sum_down(x);

可以简化为:

x = x - 1;
int y = x + sum_down(x) + sum_down(x);
return y;

可以简化为:

int y = (x-1) + sum_down(x-1) + sum_down(x-1);
return y;

可以简化为:

return (x-1) + 2*sum_down(x-1);

以数学形式,

f(N) = (N-1) + 2*f(N-1)

递归在N -1时终止。 f(-1) = 1 .

因此

f(0) = -1 + 2*1 = 1
f(1) =  0 + 2*1 = 2
f(2) =  1 + 2*2 = 5
...
f(18) = 17 + 2*f(17) = 524269
f(19) = 18 + 2*524269 = 1048556

你的程序可以这样写(对不起 c#(:

public static void Main()
{
    int i = 0;
    int j = 0;
    do
    {
        i++;
        j = sum_down(i);
        Console.Out.WriteLine("j:" + j);
    } while (j < 1000000);
    Console.Out.WriteLine("i:" + i);
}
static int sum_down(int x)
{
    if (x >= 0)
    {
        return x - 1 + 2 * sum_down(x - 1);
    }
    else
    {
        return 1;
    }
}

所以在第一次迭代时,你会得到 2,然后是 5,然后是 12...因此,您可以忽略 x-1 部分,因为与乘法相比,它会保持很少。

所以我们有:

i = 1 => sum_down ~= 4 (real is 2)
i = 2 => sum_down ~= 8 (real is 5)
i = 3 => sum_down ~= 16 (real is 12)
i = 4 => sum_down ~= 32 (real is 27)
i = 5 => sum_down ~= 64 (real is 58)

所以我们可以说sum_down(x( ~= 2^x+1。然后它只是基本的数学,2^x+1 <1 000 000,即 19。

有点晚了,但获得一个精确的非递归公式并不难。

用数学方式写出来,正如其他答案中所解释的那样:

f(-1) = 1
f(x) = 2*f(x-1) + x-1 

这与

f(-1) = 1
f(x+1) = 2*f(x) + x

(刚刚从 x 和 x-1 切换到 x+1 和 x,两种情况下的差异均为 1(

前几个 x 和 f(x( 是:

x:    -1  0  1  2  3  4
f(x): 1   1  2  5  12 27

虽然有许多任意复杂的方法可以将其转换为非递归公式,但使用简单的方法,通常有助于写出每个两个元素之间的区别:

x:    -1  0  1  2  3  4  
f(x): 1   1  2  5  12 27  
        0  1  3  7  15  

所以,对于某些 x

f(x+1) - f(x) = 2^(x+1) - 1  
f(x+2) - f(x) = (f(x+2) - f(x+1)) + (f(x+1) - f(x)) = 2^(x+2) + 2^(x+1) - 2  
f(x+n) - f(x) = sum[0<=i<n](2^(x+1+i)) - n 

例如插入一个x=0,使f(x+n) f(n)

f(x+n) - f(x) = sum[0<=i<n](2^(x+1+i)) - n  
f(0+n) - f(0) = sum[0<=i<n](2^(0+1+i)) - n  
f(n) - 1 = sum[0<=i<n](2^(i+1)) - n   
f(n) = sum[0<=i<n](2^(i+1)) - n + 1   
f(n) = sum[0<i<=n](2^i) - n + 1   
f(n) = (2^(n+1) - 2) - n + 1
f(n) = 2^(n+1) - n - 1  

不再递归。

这个怎么样:

int x = 0;
while (sum_down(x) <= 1000000)
{
    x++;
}

循环递增 x,直到 sum_down(x( 的结果优于 1.000.000。

编辑:结果将是 19。

虽然试图理解和简化sum_down()函数背后的递归逻辑是有启发性和信息性的,但这个片段往往是合乎逻辑和实用的,因为它不是试图从上下文的角度解决问题,而是在结果方面。

两行 Python 代码来回答你的问题:

>>> from itertools import *   # no code but needed for dropwhile() and count()

定义递归函数(参见R Sahu的答案(

>>> f = lambda x: 1 if x<0 else (x-1) + 2*f(x-1)

然后使用 dropwhile() 函数从列表 [0, 1, 2, 3, ....] 中删除f(x)<=1000000的元素,从而生成一个f(x) > 1000000的整数列表。注意:count()返回 [0, 1, 2, ....( 的无限"列表">

dropwhile()函数返回一个 Python 生成器,因此我们使用 next() 来获取列表的第一个值:

>>> next(dropwhile(lambda x: f(x)<=1000000, count()))
19
相关文章: