Fibonacci修改:如何修复此算法?

时间:2017-12-06 20:03:05

标签: java algorithm recursion dynamic-programming memoization

我面前有这个问题,我无法弄清楚如何解决它。 关于系列0,1,1,2,5,29,866...(除了前两个数字之外的每个数字都是前两个数字(2^2+5^2=29)的平方和)。 在第一部分中,我必须编写一个算法(不是母语,因此我不知道术语)会在系列中获得一个位置并返回它的值(6 returned 29) 这就是我写它的方式:

public static int mod(int n)
{
    if (n==1)
        return 0;
    if (n==2)
        return 1;
    else
        return (int)(Math.pow(mod(n-1), 2))+(int)(Math.pow(mod(n-2), 2));
}

但是,现在我需要算法将收到一个数字,并在(6- 29+5+2+1+1+0=38系列中返回总数。 我不知道怎么做,我正在努力,但到目前为止我真的无法理解递归,即使我写了一些正确的东西,我怎么能检查它确定?一般来说,如何达到正确的算法?

禁止使用任何额外参数。

提前致谢!

5 个答案:

答案 0 :(得分:4)

我们希望:

mod(1) = 0
mod(2) = 0+1
mod(3) = 0+1+1
mod(4) = 0+1+1+2
mod(5) = 0+1+1+2+5
mod(6) = 0+1+1+2+5+29

我们知道每个术语都定义为:

   2^2+5^2=29

因此,为了解决mod(7),我们需要将序列x中的下一个术语添加到mod(6)。

现在我们可以使用mod来解决这个术语:

 x = term(5)^2 + term(6)^2
 term(5) = mod(5) - mod(4)
 term(6) = mod(6) - mod(5)
 x = (mod(5)-mod(4))^2 + (mod(6)-mod(5))^2

因此我们可以通过评估mod(4),mod(5),mod(6)并结合结果来计算mod(7)。

当然,除非你记住这个功能,否则这将是非常低效的!

示例Python代码:

def f(n):
    if n<=0:
        return 0
    if n==1:
        return 1
    a=f(n-1)
    b=f(n-2)
    c=f(n-3)
    return a+(a-b)**2+(b-c)**2

for n in range(10):
    print f(n)

打印:

0
1
2
4
9
38
904
751701
563697636866
317754178345850590849300

答案 1 :(得分:2)

我可以想一个用你评论中的约束来做到这一点的方法,但这完全是黑客攻击。您需要一种方法来完成两件事:找到当前值并添加以前的值。一种选择是使用负数来标记其中一个函数:

int f(int n) {
    if (n > 0)
        return f(-n) + f(n-1);
    else if (n > -2)
        return 0;
    else if (n == -2)
        return 1;
    else
        return f(n+1)*f(n+1)+f(n+2)*f(n+2);
}

前8个数字输出(溢出前)是:

0
1
2
4
9
38
904
751701

我不建议使用此解决方案,但它确实满足您使用单个参数作为单个递归方法的约束。

答案 2 :(得分:2)

这个怎么样? :)

class Main {

  public static void main(String[] args) {
    final int N = 6; // Your number here.
    System.out.println(result(N));
  }

  private static long result(final int n) {
    if (n == 0) {
      return 0;
    } else {
      return element(n) + result(n - 1);
    }
  }

  private static long element(final int n) {
    if (n == 1) {
      return 0L;
    } else if (n == 2) {
      return 1L;
    } else {
      return sqr(element(n - 2)) + sqr(element(n - 1));
    }
  }

  private static long sqr(final long x) {
    return x * x;
  }
}

以下是单独的函数(element)负责查找序列中的第n个元素的想法,result负责对它们求和。最有可能的是,有一个更有效的解决方案。但是,只有一个参数。

答案 3 :(得分:0)

这是我的建议。

我们知道:

f(n)= 0; n&lt; 2

f(n)= 1; 2&gt; = n&lt; = 3

f(n)= f(n-1)^ 2 + f(n-2)^ 2; N'→3

所以:

int number = Integer.parseInt(input.getText().toString());

根据这种行为,我们必须实现一个递归函数来返回:

总计=和f(n); n = 0:k;其中k> 0

我读过你可以使用静态方法但不能在函数中使用多个参数。所以,我使用静态变量和静态方法,只是为了控制循环的执行:

f(0)= 0
f(1)= 0
f(2)= f(1) + f(0) = 1
f(3)= f(2) + f(1) = 1
f(4)= f(3) + f(2) = 2
f(5)= f(4) + f(3) = 5
and so on

输出:

class Dummy 
{

    public static void main (String[] args) throws InterruptedException {

        int n=10;

        for(int i=1; i<=n; i++)
        {
            System.out.println("--------------------------");
            System.out.println("Total for n:" + i +" = " + Dummy.f(i));
        }
    }

    private static int counter = 0;
    public static long f(int n)
    {   
        counter++;

        if(counter == 1)
        {
            long total = 0;
            while(n>=0)
            {    
                total +=  f(n);
                n--;
            }
            counter--;
            return total;
        }

        long result = 0;
        long n1=0,n2=0;

        if(n >= 2 && n <=3)
            result++; //Increase 1
        else if(n>3)
        {
            n1 = f(n-1);
            n2 = f(n-2);

            result = n1*n1 + n2*n2;
        }

        counter--;
        return result;
    }
}

我希望它可以帮到你。

更新:以下是没有静态方法的另一个版本,并且具有相同的输出:

--------------------------
Total for n:1 = 0
--------------------------
Total for n:2 = 1
--------------------------
Total for n:3 = 2
--------------------------
Total for n:4 = 4
--------------------------
Total for n:5 = 9
--------------------------
Total for n:6 = 38
--------------------------
Total for n:7 = 904
--------------------------
Total for n:8 = 751701
--------------------------
Total for n:9 = 563697636866
--------------------------
Total for n:10 = 9011676203564263700

答案 4 :(得分:0)

<强>非递归| Memoized 你不应该使用递归,因为它的性能不佳。 请改用memoization。

def FibonacciModified(n):
    fib = [0]*n
    fib[0],fib[1]=0,1
    for idx in range(2,n):
        fib[idx] = fib[idx-1]**2 + fib[idx-2]**2
    return fib

if __name__ == '__main__':
    fib = FibonacciModified(8)
    for x in fib:
        print x

输出:

0
1
1
2
5
29
866
750797

以上将计算系列中的每个数字[不超过]。 在递归过程中,系列中的一个元素将被计算多次,而不管该数字是否在之前计算过。

http://www.geeksforgeeks.org/program-for-nth-fibonacci-number/