1. 程式人生 > >遞推之猴子爬山

遞推之猴子爬山

遞推是利用問題本身所具有的遞推關係求解問題的方法。所謂遞推,是在命題歸納時,可以由數量分別為n-k,…,n-1的情形推得數量為n的情形,或者反過來由數量分別為i+k,…,i+1的情形推出數量為i的情形。
我們大家比較熟悉的應該就是斐波那契數列了;這裡給大家講一下稍微複雜一點的遞推——猴子爬山問題。

一個猴子在一座有30級臺階的小山坡上跳躍,猴子一步可以跳躍1級或者3級,試求上山一共有多少種不同的走法?

設爬k級臺階的不同爬法有f(k)種,
(1)尋找f(k)的遞推關係。上山最後一步到達第30級臺階完成上山,共有f(30)種不同的走法;到第30級臺階之前呢?無非是在第29級(上跳1級就行了),有f(29)種;或者位於第27級(上跳3級就行了),有f(27)種;於是f(30)=f(29)+f(27);
以此類推,有以下遞推關係:
f(k)=f(k-1)+f(k-3) (k>3);

(2)確定初始條件
f(1)=1;
f(2)=2;
f(3)=2;

(3)code如下:

int main()
{
int k,n;
long f[1000];
printf("請輸入臺階總數n:");
scanf("%d",&n);
f[1]=1;
f[2]=2;
f[3]=3;
for(int k=4;k<=n;k++)
  f[k]=f[k-1]+f[k-3];
printf("s=%1d",f[n]);
}

問題引申:設爬n級臺階,一步有m種跨法,一步跨多少級均從鍵盤輸入,求共有多少種不同的爬法。

這是一個分級遞推問題,設爬山t級臺階的不同爬法為f(t),從鍵盤輸入的m個整數分別為x(1
),x(2),x(3),.........,x(m) (約定x(1)<x(2)<...x(m)<n) 首先探討f(t)的遞推關係: 當t<x(1)時,f(t)=0,f(x(1))=1 (初始條件) 當x(1)<t<=x(2)時,第1級遞推,f(t)=f(t-x(1)) 當x(2)<t<=x(3)時,第2級遞推,f(t)=f(t-x(1))+f(t-x(2)) ....... 一般地,當x(k)<t<=x(k+1),k=1,2,,...,m-1, 有第k級遞推: f(t)=f(t-x(1))+f(t-x(2
))+....+f(t-x(k)) 當x(m)<t時,有第m級遞推: f(t)=f(t-x(1))+f(t-x(2))+...+f(t-x(m)) 當t=x(2)或x(3)...x(m)時,還要加1,因為t本身就是一個一步到位的爬法,則 f(t)=f(t)+1; 我們所求的目標就是 f(n)=f(n-x(1))+f(n-x(2))+...+f(n-x(m)) 再設計遞推的過程中可以把臺階數記為陣列x(m+1) main() { int i,j,k,m,n,t,x[10]; long f[200]; printf("請輸入總檯階數n:"); scamf("%d",&n); printf("一次有幾種跳法:"); scanf("%d",&m); printf("請從小到大輸入一步跳幾級.\n"); for(i=1;i<=m;i++) { printf("第%d個一步可以跳級數:",i); scanf("%d",&x[i]); } for(i=1;i<=x[1]-1;i++) f[i]=0; //確定初始條件 x[m+1]=n; f[x[1]]=1; //初始條件 for(k=1;k<=m;k++) //一共m種爬法,實現對每一種爬法的累加 for(t=x[k]+1;t<=x[m+1];t++) { f[t]=0; for(j=1;j<=k;j++) f[t]=f[t]+f[t-x[j]];//按公式實現累加 if(t==x[m+1]) f[t]=f[t]+1; } printf("共有不同的爬法種數為:%d",f[n]-1); //因為用到了x[m+1],將他也看成了一步走法,所以減1