C++ 为什么我的斐波那契动态规划不';你不能给出一个线性时间吗?

C++ 为什么我的斐波那契动态规划不';你不能给出一个线性时间吗?,c++,algorithm,C++,Algorithm,我正在看这个。基本上,它说使用字典(python语言?)将使计算从时间O(n^2)到O(n)的斐波那契 我已经编写了以下代码,fibo1应该是O(n),但实际上它运行得非常慢fibo2是正常的递归,它是O(n^2)解,但实际上它比fibo1运行得快得多。我怎么能理解呢 #include <iostream> #include <map> int fibo1(int i, std::map<int,int>& m); int fibo2(int i);

我正在看这个。基本上,它说使用
字典
(python语言?)将使计算从时间O(n^2)到O(n)的斐波那契

我已经编写了以下代码,
fibo1
应该是O(n),但实际上它运行得非常慢
fibo2
是正常的递归,它是O(n^2)解,但实际上它比
fibo1
运行得快得多。我怎么能理解呢

#include <iostream>
#include <map>
int fibo1(int i, std::map<int,int>& m);
int fibo2(int i);

int main()
{
    std::map<int,int> m;
    m[1] = 1; m[2] = 1;
    int n = 40;
    std::cout << fibo1(n,m);
    //std::cout << fibo2(n);
    return 0;
}

int fibo1(int i, std::map<int,int>& m)   {
    if(m[i]==0)   {
        return fibo1(i-1,m)+fibo1(i-2,m);
    }
    return m[i];
}

int fibo2(int i) {
    if(i==1 || i==2) {
        return 1;
    }

    return fibo2(i-1)+fibo2(i-2);
}
#包括
#包括
int fibo1(int i,标准::map&m);
int-fib2(int-i);
int main()
{
std::map m;
m[1]=1;m[2]=1;
int n=40;

std::cout您从未在
m[n]
处实际编写
fib[n]
,因此您从未查找任何内容并始终重新计算它。使用
m[i]=fibo1(i-1,m)+fibo1(i-2,m);
在if语句中,而不是在返回行中。

在fibo1方法中,您只返回值,而没有将映射设置为正确的值

int fibo1(int i, std::map<int,int>& m)   {
if(m[i]==0)   {
    m[i] = fibo1(i-1,m)+fibo1(i-2,m);
}
return m[i];
}
intfibo1(inti,std::map&m){
如果(m[i]==0){
m[i]=fibo1(i-1,m)+fibo1(i-2,m);
}
返回m[i];
}

此外,你应该考虑使用一个简单的矢量而不是一个映射来获得更好的性能

你不把结果存储在地图上,你应该记住,正在做的查找非常昂贵,所以你应该避免对同一个键的多次查找:

int fibo1(int i, std::map<int,int>& m)   {
    int &value = m[i];
    if( value == 0)   {
        value = fibo1(i-1,m)+fibo1(i-2,m);
    }
    return value;
}
intfibo1(inti,std::map&m){
int&value=m[i];
如果(值==0){
值=fibo1(i-1,m)+fibo1(i-2,m);
}
返回值;
}

为什么没有评论投票否决?很可能你所说的
字典提供了O(1)插入/查找行为。
std::map
据我所知有O(log(n))插入/查找。不过你可以使用
unordered_map
进行O(1)行为。而且,你还需要分配
m[I]
在返回到
if
语句中之前。@buzhidao分析您的代码以找到瓶颈。“为什么没有评论投票否决?”这可能意味着您应该改进您的问题。@zahir unordered_map通常不需要对每次否决投票进行评论。@zahir unordered_map就像python中的
dictionary
结构——一个哈希表?所以,撇开bug不谈,
m
的目的是缓存已经计算过的值?这些值将用于1到n。这听起来很像一个数组或向量。映射的开销要大得多,在这里没有任何好处。哈哈,捕捉得不错。我讨厌这种错误。这就像你的大脑用你头脑中的代码填充了你写的代码,而你错过了它。你必须一行一行地执行你头脑中的代码,而不是“阅读”它。