猴子爬山與分級遞推思想

來源:互聯網
上載者:User

一、特殊情況

 

1.問題提出

     一個頑猴在一座有30級台階的小山上爬山跳躍。上山一步可上跳1級或3級,求上山有多少種跳法。

2.解題思路

   達到第30級之前位於哪一階呢??有兩種情況,其一是第29級,一步跳一階到達,其二是第27級,一步跳三階到達。

   所以有:

   f(30) = f(29) + f(27)

   其他以此類推,一般地有遞推關係:

   f(k) = f(k - 1) + f(k - 3)

而初始條件為:

f(1) = 1

f(2) = 1  (1+1)

f(3) = 2  (1+1+1, 3)

 

3.程式碼

// 猴子爬山n級台階,一步跨1級或3級<br />#include <stdio.h></p><p>int main(void)<br />{<br />int k, n;<br />long f[1000];// f[i]存放跳i級台階共有多少種跳法</p><p>printf("請輸入台階總數n:");<br />scanf("%d", &n);<br />f[1] = 1; f[2] = 1; f[3] = 2;<br />for (k = 4; k <= n; k++)<br />f[k] = f[k - 1] + f[k - 3];<br />printf("跳%d級台階共有%d種跳法/n", n, f[n]);</p><p>return 0;<br />}

 

二、一般情況

1.問題深入

    將問題的參數一般化,爬山台階有n級,一步有同種跳法,整數n與m種跳法各為多少級均為鍵盤輸入。

2.分級遞推演算法設計

    設爬t級台階上山的不同爬法為f(t),設從鍵盤輸入一步跨多少級的m個整數分別為x(1),x(2),...,x(m)(約定x(1)<x(2)<...<x(m))。

    因為一步能跨的台階數x(i)為鍵盤輸入,事前並不知道,因此不能在設計時簡單地確定f(x(1)),f(x(2)),...。

    事實上,可以把初始條件放在分級遞推中求取,應用多種關係分組遞推完成遞推。

 

   首先,探討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),或t=x(3),...,或t=x(m)時,按上遞推求f(t)外,還要加上1。道理很簡單,因此此時t本身即為一個一步到位的爬法。為此,應在以上遞推基礎上添加:

  f(t)=f(t)+1 (t=x(2),x(3),...,x(m))

  我們所示的目標為:

  f(n)=f(n-x(1))+f(n-x(2))+...+f(n-x(m))

 

  特殊處理

  在遞推設計中我們可把台階數n記為數組元素x(m+1),這樣處理是巧妙的,可以按相同的遞推規律遞推計算,簡化演算法設計,最後一項f(x(m+1))即為所求f(n)。

  最後輸出f(n)時必須把額外所添加的1減去。

 

2.代碼實現

#include <stdio.h></p><p>int main(void)<br />{<br />int i, j, k, m, n, x[10];<br />long f[200];</p><p>printf("請輸入總台階數:");<br />scanf("%d", &n);<br />printf("一次有幾種跳法:");<br />scanf("%d", &m);<br />printf("請從小到大輸入一步跳幾階/n");<br />for (i = 1; i <= m; i++)// 輸入m個一步跳級數<br />{<br />printf("第%d個一步可跳級數:", i);<br />scanf("%d", &x[i]);<br />}</p><p>// 確定初始條件<br />for (i = 1; i <= x[1] - 1; i++)<br />f[i] = 0;<br />x[m + 1] = n;<br />f[x[1]] = 1;</p><p>for (k = 1; k <= m; k++)<br />{<br />for (i = x[k] + 1; i <= x[k + 1]; i++)<br />{<br />f[i] = 0;<br />for (j = 1; j <= k; j++)// 按公式累加實現分級<br />f[i] = f[i] + f[i - x[j]];<br />if (i == x[k + 1])<br />f[i] = f[i] + 1;<br />}<br />}</p><p>printf("共有不同的跳法種數為:%d/n", f[n] - 1);</p><p>return 0;<br />}

 

 

                                              

     選自《趣味C程式設計》

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.