C ++中的简单重复

时间:2014-11-12 23:51:15

标签: c++ algorithm recurrence

Simple RecurrenceMax。得分0

  

我们的英雄 - 亚历克斯已经研究了一个星期。他有   最近得到了一个复发关系来解决其中的一部分   研究。但他没有时间。你能做到吗?

     

递归关系如下:f(n)= 3 * f(n-1)+ 2 * f(n-2)+ 2   * g(n-1)+3 * g(n-2),g(n)= g(n-1)+ 2 * g(n-2)。

     

给出初始值f(1),f(0),g(1),g(0)。

     

你必须输出f(N)mod 10 ^ 9。

输入:

  

在第一行中,您将获得4个数字:f(1),f(0),g(1),g(0)   分别。在下一行中,您将获得一个整数N。

输出:

  

输出f(N)mod 10 ^ 9。

约束:

  

1&lt; = f(0),f(1),g(0),g(1)&lt; = 10   1 <= N <= 10 ^ 18

样本输入(明文链接)

  

1 1 1 1   4   样本输出(明文链接)   162

这确实是一个非常简单的问题。我只是用6个变量f0,f1,f2,g0,g1,g2进行迭代来解决它。在循环中,我首先计算g2,f2,然后f0 = f1,f1 = f2,g0 = g1,g1 = g2。数据类型在c ++中是长对齐的无符号。

然而,时间限制是1秒,我得到1.06秒。因此,我在测试中仅通过了一个测试用例,其他时间超过了#34;。有没有更快的方法来解决它?

我的代码是:

#include<iostream>
using namespace sdt;

int main()
{
    unsigned long long f0, f1, g0, g1, f2, g2;
    unsigned long long N;
    cin>>f1>>f0>>g1>>g0;
    cin>>N;
    for(unsigned long long i=2; i<N+1; i++)
    {
        f2=3*f1+2*f0+2*g1*3*g0;
        g2=g1+2*g0;
        f0=f1;
        f1=f2;
        g0=g1;
        g1=g2;
    }
    unsigned long long result=f2%1000000000;
    cout<<result;
    return 0;
}

2 个答案:

答案 0 :(得分:2)

鉴于重复可以写为

enter image description here

具有f(1)f(o)g(1)g(0)给出的基本条件。现在,要计算f(n),我们必须将系数矩阵提高到幂n - 1。幸运的是,这可以使用log(n)矩阵乘法来完成。这是exponentiation的一个着名问题。

由于矩阵大小很小,因此复杂度为O(log(n))

答案 1 :(得分:1)

1 - 代码与递归关系不同。代码应该是:

f2=3*f1+2*f0+2*g1+3*g0;

2 - 优化代码的一种可能方法是通过这样做来减少繁重计算的数量,这是本例中的乘法:

f2=3*(f1+g0)+2*(f0+g1);

但是,我认为编译器的优化器会自动为您执行此操作,但您可以尝试自己确定。