ACM選修(遞迴)

2021-07-03 04:40:51 字數 3060 閱讀 4330

遞迴演算法的構成:基本項和歸納項

例題一 求n的階乘n!(n>0)

終止狀態:當n=1時,n!=1

歸納項:當n>1時,n!=n*(n-1)!

int fact(int n)

例題二 fibonacci序列:1,1,2,3,5,8,13…

定義為:f0=f1=1   fi=fi-1+fi-2(i>1)

終止狀態:當i=1或i=0時,fi=1

歸納項:當i>1時,fi=fi-1+fi-2

int fib(int i)

1.求單鏈表的表長——遞迴演算法

方法一

int length(struct node *h)

方法二

int counter=0;

void length(struct node*h)

}

方法三

int counter=0;

void length(struct node*h)

}

方法四

void length(struct node*h,int &x)

}

2.輸出單鏈表各結點的元素值

方法一

void print

}

方法二
void print

}

問題:出棧序列

演算法設計思路 窮舉法

思想:就是用窮舉的方法列出所有的情況

演算法:用遞迴演算法進行所有情況的搜尋

void counter1(int sout,int sin,int &sum)

//sin表示在棧中的元素個數

//sout表示未進棧的元素個數,sum為統計數目

void counter2(int sout,int sin,int &sum)

//sin表示在棧中的元素個數

//sout表示未進棧的元素個數,sum為統計數目

else counter2(sout-1,sin+1,sum);

if(sin>0) counter2(sout,sin-1,sum);

}

問題:張明與朋友們一同去上海世博會參觀,世博會的門票為50元,張明發現乙個奇怪的現象:在排隊購票的2n個人中,總有n個人拿著面值為100元的鈔票,而另外n個人拿的是面值為50元的鈔票。張明想知道在這種情況下這2n個人共有多少中排隊方式,使售票處不至於出現找不開錢的局面(假設售票處原來沒有零錢的情況)?

演算法設計思路

思路:根據影響因素進行函式關係的構建

由於題目中影響序列個數的因素主要是拿50元和100元的當前人數,因此,我們可以設定:

x為拿50元的當前人數,y為拿100元的當前人數。

於是有我們就可以構建出函式f(x,y)。

分情況討論函式關係

y=0,則只有拿50元的人,於是f(x,0)=1;

x1) return f(n-1)+2*(n-1);

}問題描述:

將整數n分成k份,且每份不能為空,任意兩種分法不能相同(不考慮順序),問有多少種不同的分法。(61  1  10          2  2  8         3  3  6       4  4  4

1  2  9             2  3  7         3  4  5

1  3  8             2  4  6          

1  4  7             2  5  5

1  5  6

思路逐步將範圍縮小。

每個位置都進行逐個數值的處理分析。

即第乙個數的選擇方法,接著考慮第二數的選擇方法,如此類推。

構造遞迴函式

於是設函式f(n,k)表示總的分法,它可按第乙個分解數的不同,分為i類(0

fi=f((n-i)-(k-1)*(i-1),k-1) = f(n-(i-1)*k-1,k-1
因此,我們得出如下的遞迴函式:

f(n,k)=f1+f2+…+f[n/k]// 特別地f(n,1)=1,f(n,2)=n/2

f(n,k)=f1+f2+…+f[n/k]// 特別地f(n,1)=1,f(n,2)=n/2
int f(int n,int k)   

}

void main()

else

} }

int main()

如何輸出每種分法的結果

如何儲存每種分法的各個取值。

fi=f(n-i,k-1) 從i開始處理,將這個i值儲存到陣列中

問題公升級

任何乙個大於1的自然數n,總可以分拆成若干個小於n的自然數之和。

例如:n=2可以分拆為1種:2=1+1

n=3可以分拆為2種: 3=1+2   3=1+1+1

n=4可以分拆為4種:4=1+3   4=1+1+2   4=1+1+1+1  4=2+2

注意:分拆n=5時,5=2+3    5=3+2 是同一種拆分。

思路分析

拆分方法(以n=7為例)

第一步:將n拆分為2個數

7=1+6 7=2+5 7=3+4       

拆分特點:第2加數總大於第乙個加數,因此第乙個加數從1變化到n/2。

第二步:只要第2個加數仍然大於1,就可按第一步重複拆分。

7=1+6    可以繼續拆分為 7=1+1+5 7=1+2+4 7=1+3+3

其中7=1+1+5又可以繼續拆分獲得7=1+1+1+4 7=1+1+2+3…

void f(int n,int now)

{ int i , j;

if (n

ACM選修課5 貪心法

部分最優,結果最優 需證明 貪心問題的特徵 1 乙個問題的最優解包含其子問題的最優解 2 整體最優解可以通過區域性的最優的選擇 老鼠的旅行 include using namespace std struct sa data 1001 intcmp const sa a,const sa b int...

ACM選修課1 數學問題

memset 函式 memset 陣列名,1 0 1,sizeof a 重置為1是陣列為任意正數 求乙個數的位數 int log10 n 1,公式log10 i i 必須為double型別 the hardest problem ever include using namespace std in...

ACM程式設計選修課 1081 堆(BFS)

time limit 1 sec memory limit 128 mb submit 26 solved 9 3110 310 5 3 1 21 3 51 2 3 4 5 3 12 1 2 42 5 yes noyes 嗯好久之前的題了。由於自己樹這方面不是很懂也沒學過資料結構,然後就沒敢做。趁著...