N階台階問題(詳解)


 原創


 問題描述:

  有N階台階,每一步可以走1步台階或者2步台階,求出走到第N階台階的方法數。

解題思路:

  1.    類似於建立樹的過程

     

          1                      2

       1      2                   1     2

      1        2      1    2                 1       2        1       2
     ……..                   ........

     如上,建立一棵根節點為1和一棵根節點為2的二叉樹,分別表示台階第一步跨1步和跨2步,

     第二層各有兩種選擇,分別是跨1步和2步,接下來的每一層都有這兩種選擇,如何跨

     越的階數等於N,計數變量+1,如果大於N,返回繼續走其他路徑。

       (由於n到45左右時數據已經爆炸,這種暴力遞歸法在n較大時系統出不來數據了)

 1 #include<stdio.h>
 2 
 3 int count;    //計數變量
 4 
 5 void sos(int n,int step)
 6 {
 7     if(step>n)    //大於n,這種方法不行 
 8         return;
 9     if(step==n)
10     {
11         count++;
12         return;
13     } 
14     
15     sos(n,step+1);    //樹1
16     sos(n,step+2);    //樹2
17 }
18 
19 int main()
20 {
21     int n;
22     scanf("%d",&n);    //n階台階
23     
24     sos(n,0); 
25     printf("%d",count);
26     return 0;
27 } 

   2. 動態規划法

     有一個規律: F(n)= F(n-1)+ F(n-2);

     F(n)表示當有n階台階時有F(n)種方法;比如F(1)= 1;F(2)= 2;F(3)= F(1)+ F(2)= 3;

     下面我用我的思路盡可能讓大家理解這個公式:

     1. 可以這樣想,需要跨越n層階梯,那么第一步我跨1層階梯,那么剩下n-1層階梯,跨越這n-1階台階的方法

       就有F(n-1)方法; 同理,第一步跨2層階梯,那么跨越剩下的n-2層階梯就有F(n-2)種方法。

       所以跨越n層階梯的方法數  F(n)= F(n-1)+ F(n-2);

      2.   如果上面大家不理解,還可以這樣理解,假如我們已經知道了F(n-1)和F(n-2),求F(n);

       在F(n-2)的基礎上,我們可以通過一次跨2層階梯到達第n層,也可以通過先跨1步,再跨1步的方式到達

       第n層。 我們可以這樣理解,如果一次性跨2層階梯,我們只是在每一種跨越n-2層階梯方式的基礎上再加上

       2就能到達第n層階梯了,所以方法還是F(n-2);

       如果先跨1步,這樣加上原來的n-2步,就一共走了n-1步了,方法數就是F(n-1)了,然后再跨多1步,同

       上,我們只是在每一種跨越n-1層階梯方式的基礎上再加上1就能到達第n層階梯了,所以方法還是F(n-1)。

       希望這樣說大家能理解。

       如有疑問和建議,非常歡迎大家發表評論。

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 
 4 int sos(long long *arr,int n)
 5 {
 6     if(n<0)
 7         return 0;
 8     if(n==0 || n==1 || n==2)
 9         return n;
10         
11     if(arr[n-1]==0)    //等於0表示沒有被算出
12         arr[n-1]=sos(arr,n-1);    //沒有被算出,就先算出
13         
14     if(arr[n-2]==0)    //同理
15         arr[n-2]=sos(arr,n-2); 
16         
17     return arr[n-1]+arr[n-2];    //等到算出arr[n-1]和arr[n-2]后就可以算出arr[n]了 
18 }
19 
20 int main()
21 {
22     int n;
23     scanf("%d",&n);    //輸入台階數 
24     
25     long long *arr;
26     arr=(long long *)malloc(sizeof(long long)*(n+1));    //分配n+1個空間 
27     
28     int i;
29     for(i=0;i<=n;i++)    //數組全部元素置0 
30         arr[i]=0;
31     
32     printf("%I64d",sos(arr,n));
33     
34     free(arr);
35     return 0;
36 }

2018-04-06                                                      


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM