遞迴和遞推,遞迴遞推

來源:互聯網
上載者:User

遞迴和遞推,遞迴遞推

遞迴的概念

一個函數、過程、概念或資料結構,如果在其定義或說明內部直接或間接地出現有其本身的引用,或者是為了描述問題的某一狀態,必須用到它的上一狀態,而描述上一狀態,又必須用到它的上一狀態……這種用自己來定義的方法,稱之為遞迴或者遞迴定義。
在程式設計中,過程或函數直接或者間接調用自己,就稱為遞迴調用

遞迴過程實際上藉助於一個遞迴工作棧來實現的。
首先問題向一個方向一步一步分解,既問題規模逐漸降低,這樣,問題向一極推進的過程稱之為遞迴過程;
然後這些問題又按後提出先解決的順序依次得到解決,最後得到原問題的解。這樣,在子問題得到逐一解決的基礎上,最後回到原問題的解的變化過程,稱之為迴歸過程。

遞迴定義的要素

1、遞迴邊界或終止條件。
2、遞迴定義,使問題向邊界條件轉化的規則。

var
  n:integer;
function fibonacci(x:integer):integer;
begin
  if (x=0) or (x=1) then exit(1);
  exit(fibonacci(x-1)+fibonacci(x-2));
end;
begin
  readln(n);
  writeln(fibonacci(n));
end.


集合的劃分

設s是一個具有n個元素的集合,s={a1,a2,……,an},現將s劃分成K個滿足下列條件的子集合s1,s2,……,sk ,且滿足:
        1.si≠φ
        2.si∩sj=φ         (1≤i,j≤k  i≠j)
        3.s1∪s2∪s3∪…∪sk=s
則稱s1,s2,……,sk是集合s的一個劃分。它相當於把s集合中的n個元素a1 ,a2,……,an 放入k個(0<k≤n<30)無標號的盒子中,使得沒有一個盒子為空白。請你確定n個元素a1 ,a2 ,……,an 放入k個無標號盒子中去的劃分數s(n,k)。

先舉個例子,設S={1,2,3,4},k=3,不難得出s有6種不同的劃分方案,即劃分數s(4,3)=6,具體方案為:
{1,2}∪{3}∪{4}    
{1,3}∪{2}∪{4}    
{1,4}∪{2}∪{3}
{2,3}∪{1}∪{4}    
{2,4}∪{1}∪{3}    
{3,4}∪{1}∪{2}


考慮一般情況,對於任意的含有n個元素a1 ,a2,……,an的集合s,放入k個無標號的盒子中去,劃分數為s(n,k),我們很難憑直覺和經驗計算劃分數和枚舉劃分的所有方案,必須歸納出問題的本質。
下面考慮對任一個元素an,則必然出現以下兩種情況:
1、{an}是k個子集中的一個,於是我們只要把a1,a2,……,an-1 劃分為k-1子集,便解決了本題,這種情況下的劃分數共有s(n-1,k-1)個;
2、{an}不是k個子集中的一個,則an必與其它的元素構成一個子集。則問題相當於先把a1,a2,……,an-1 劃分成k個子集,這種情況下劃分數共有s(n-1,k)個;然後再把元素an加入到k個子集中的任一個中去,共有k種加入方式,這樣對於an的每一種加入方式,都可以使集合劃分為k個子集,因此根據乘法原理,劃分數共有k*s(n-1,k)個。


綜合上述兩種情況,應用加法原理,得出n個元素的集合{a1,a2,……,an}劃分為k個子集的劃分數為以下遞迴公式:
s(n,k)=s(n-1,k-1)+k*s(n-1,k) (n>k,k>0)。


確定s(n,k)的邊界條件

首先不能把n個元素不放進任何一個集合中去,即k=0時,s(n,k)=0;
也不可能在不允許空盒的情況下把n個元素放進多於n的k個集合中去,即k>n時,s(n,k)=0;
再者,把n個元素放進一個集合或把n個元素放進n個集合,方案數顯然都是1,即k=1或k=n時,s(n,k)=1。
可以得出劃分數s(n,k)的遞迴關係式為:
s(n,k)=s(n-1,k-1)+k*s(n-1,k)            (n>k,k>0)
s(n,k)=0                                     (n<k)或(k=0)
s(n,k)=1                                     (k=1)或(k=n)


遞迴與非遞迴的轉化

在遞迴調用的過程中,由於要保留每次調用時的參數和局部變數,而且要經過逐層調用和逐層返回兩大過程,程式對於時間和儲存空間的耗費可以說是巨大的。因此,在一個問題對於時空要求較高的情況下,有時不得不將遞迴方法轉化成非遞迴方法,這一過程,常常稱之為消除遞迴。消除遞迴的過程,其本質上就是要求類比複雜的遞迴工作棧的變化過程,雖然遞迴與非遞迴在形式上大多能夠相互轉化,但是,非遞迴的編程難度要遠遠高於遞迴的方法

遞推

在問題類型中,每個資料項目都和它前面的若干個資料項目(或後面的若干個資料項目)有一定的關聯,這種關聯一般是通過一個遞推關係式來表示的。求解問題時就從初始的一個或若干個資料項目出發,通過遞推關係式逐步推進,從而得到最終結果。這種求解法就叫遞推法


var
  a:array[0..100] of longint;
  i:integer;
begin
  readln(n);
  a[0]:=1;
  a[1]:=1;
  for i:=2 to n do
    a[i]:=a[i-1]+a[i-2];
  writeln(a[n]);
end.


演算法架構

1、確定求解初始條件
2、求出遞推公式
3、從邊界出發進行順推或反向推算
4、輸出結果


具體詳見:

http://download.csdn.net/download/boyxiejunboy/8913331

http://download.csdn.net/download/boyxiejunboy/8913339

http://download.csdn.net/download/boyxiejunboy/8913343

(不用積分下載哦)

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.