斐波那契數列切入動態規劃
阿新 • • 發佈:2021-08-06
斐波那契數列切入動態規劃
動態規劃指儲存已出現過的值。
1.普通遞迴
int Fibonacci(int n){
if(n==0){
return 0;
}
if(n<=2){
return 1;
}
return Fibonacci(n-1)+Fibonacci(n-2);
}
2.備忘錄法
#include<bits/stdc++.h> using namespace std ; int fib(int n,int Memo[]); int Fibonacci(int n) { if(n<=0) return n; int Memo[n+1]; for(int i=0;i<=n;i++) Memo[i]=-1; return fib(n, Memo); } int fib(int n,int Memo[]) { if(Memo[n]!=-1) return Memo[n]; //如果已經求出了fib(n)的值直接返回,否則將求出的值儲存在Memo備忘錄中。 if(n<=2) Memo[n]=1; else Memo[n]=fib( n-1,Memo)+fib(n-2,Memo); return Memo[n]; } int main(){ cout<<Fibonacci(12)<<endl; return 0; }
以上兩種方法都是自頂向下的由求父值轉向求子值的遞迴思想;
於是演變出第三種思想,先求小運算元;
3.自下至上的動態規劃
int Fibonacci(int n){
int memo[n+1];
memo[0]=0;
memo[1]=1;
for(int i=2;i<=n;i++){
memo[i]=memo[i-1]+memo[i-2];
}
return memo[n];
}
既然 我們要求fib(n),我們就把所有運算元儲存在一個數組中,依次正向推進得到結果,遞迴是反相推演。
進一步推演,每次參與計算只需有規律推進的三個運算元。
int Fibonacci(int n){
int memo_0=0;
int memo_1=1;
int memo_n;
for(int i=2;i<=n;i++){
memo_n=memo_0+memo_1;
memo_0=memo_1;
memo_1=memo_n;
}
return memo_n;
}
這三個運算元是有規律依次遞進的,所以可以節省陣列的空間。感覺像是連結串列指標。