如何在没有反复试验的情况下解决此递归问题

时间:2015-10-13 06:54:36

标签: c++ algorithm recursion

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?

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

5 个答案:

答案 0 :(得分:8)

递归逻辑:

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

答案 1 :(得分:4)

你的程序可以用这种方式编写(抱歉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 &lt; 1 000 000是19。

答案 2 :(得分:4)

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

以数学方式编写,正如其他答案所解释的那样:

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  

不再递归了。

答案 3 :(得分:1)

这个怎么样:

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

循环递增x直到sum_down(x)的结果高于1.000.000。

编辑:结果将是19。

虽然试图理解和简化sum_down()函数背后的递归逻辑具有启发性和信息性,但这个片段往往是逻辑和实用的,因为它不会尝试解决上下文中的问题,而是结果条款。

答案 4 :(得分:0)

两行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的整数列表。 1}}。注意:count()返回[0,1,2,....]

的无限“列表”

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

>>> next(dropwhile(lambda x: f(x)<=1000000, count()))
19