1. 程式人生 > >走樓梯遞迴遞推的演算法總結

走樓梯遞迴遞推的演算法總結


走樓梯的演算法總結
(1).一次可以走一階或兩階
(2).一次可以走一階或兩階或三階

(3). 一次可以走一階或兩階,最終走偶數步,或者奇數步
兩種實現方式
(1).遞迴
(2).遞推 
(1)遞迴的思想:就是一個問題可以拆分成他的子問題
子問題和原問題有相同的結構
每一次縮小一次問題的規模,規模最小的時候就是遞迴函式的出口
一層遞迴呼叫結束後會返回給上一層,
依次類推,等到壓棧的函式全部出棧遞迴呼叫結束
遞迴其實是利用棧的後進先出來實現功能的 
(2)遞推的演算法的思想:每一步都是由它的上一步推過來的,一步一步的去算,找規律,用陣列去實現。

int f(int n)  //遞迴(1) 
{
	if (n==1) //遞迴函式的出口 
	  return 1;
	if (n==2)  //遞迴函式的出口 
	  return 2;
	return f(n-1)+f(n-2);
}
遞迴(2) int f(int n)  
{
	if (n==1)
	   return 1;
	if (n==2)
	   return 2;
	if (n==3)
	   return 4;
	return f(n-1)+f(n-2)+f(n-3);
}

int main ()
{
    int i=f(3);
	printf ("%d\n",i);  	
	return 0;
} 
/*
等下次我再介紹一下漢諾塔問題,雙重遞迴比較的複雜難懂。
而搞懂這些問題,才會對資料結構中的樹,有更清晰的認識。
*/ 

下面是遞推演算法的實現
# include <bits/stdc++.h>
using namespace std;
const int maxn=1000;
//(1).一次可以走一階或兩階
//(2).一次可以走一階或兩階或三階
//(3).一次可以走一階或兩階,總共要走偶數步
//求一共有多少種方法。 
//int f[1000];
//(1) 
int main ()
{
  int n;
  f[1]=1;
  f[2]=2;
  for (int i=3;i<=100;++i)
     f[i]=f[i-1]+f[i-2];
  printf ("%d\n",f[5]);
  return 0;	
} 
//(2)
int main ()
{
   int n;
  f[1]=1;
  f[2]=2;
  f[3]=4;
  for (int i=4;i<=100;++i)
     f[i]=f[i-1]+f[i-2]+f[i-3];//每一次都是用它的上一步去推出來的。
	                           //這一步可以選擇走一步或者兩步或者三步。 
  printf ("%d\n",f[5]);
  return 0;		
}
//(3)
int main ()
{
   int f[100][2];
   memset (f,0,sizeof(f));
   f[1][0]=1;
   f[1][1]=0,f[2][0]=1,f[2][1]=1;  //0代表偶數,1代表偶數,先把前面的項推出來。 
   for (int i=3;i<=100;++i)
      {
      	f[i][0]=f[i-1][1]+f[i-2][1]; //第i階是偶數,那麼i-1階,i-2階肯定是奇數了,依次類推。 
      	f[i][1]=f[i-1][0]+f[i-2][0];
	  }
    printf ("%d\n",f[5][1]); 
	return 0;
} 
/*
遞推的演算法就是找規律的,堆骨牌問你一共有多少種方法也是如此的,這一步是依據他的上一步來的。
*/