ACM入門演算法之---遞迴專場
阿新 • • 發佈:2019-01-03
遞迴演算法就是在函式或子過程的內部,直接或者間接地呼叫自己的演算法,在ACM中它是一個入門級的演算法,題目一般非常簡單。它一般解決三類問題:
(1) 資料的定義是按遞迴定義的。(Fibonacci函式)
(2) 問題解法按遞迴演算法實現。(回溯)
(3) 資料的結構形式是按遞迴定義的。(樹的遍歷,圖的搜尋)
遞迴演算法解決問題的特點:
(1) 遞迴就是在過程或函式裡呼叫自身。
(2) 在使用遞迴策略時,必須有一個明確的遞迴結束條件,稱為遞迴出口。
(3) 遞迴演算法解題通常顯得很簡潔,但遞迴演算法解題的執行效率較低,並且在遞迴呼叫的過程當中系統為每一層的返回點、區域性量等開闢了棧來儲存。遞迴次數過多容易造成棧溢位等。所以一般不提倡用遞迴演算法設計程式
遞迴是非常工具性的演算法,常用於其他演算法的實現,例如遞迴常與分治演算法一同出現,也在深搜,遞迴建樹,樹的遞迴遍歷等等地方使用,在很多的模擬題中也有很大的作用,往往使得程式碼變得十分清晰和精短。
同時ACM中遞迴的題目也相對簡單以下是我做過的一些簡單題的總結。
下面HDOJ 2044 到 HDOJ 2050是很好的入門級別的遞迴練習,當然,有的題還是很有難度。
2044 | 36.87%(8238/22344) |
解題思路:1)每到一個點的路徑數肯定等於它左邊和左下方(左上方)的路徑之和。
2)設從a走到b之間一共走n步,則有:
dp[n]=dp[n-1]+dp[n-2]; dp[n-1]=dp[n-2]+dp[n-3]..............
貼下程式碼:
HDOJ 2045/2046/2047/2048/2049差不多都是一樣的思想,大家就慢慢推理吧。#include <iostream> #include <cstdio> #include <cmath> using namespace std; long long a[55]; int T,n,m; int main() { a[0]=0; a[1]=1; a[2]=2; for (int i=3; i<=50; i++) { a[i]=a[i-1]+a[i-2]; } cin >> T; while (T--) { cin >> n >> m; cout << a[m-n] << endl; } return 0; }
重點說說 HDOJ2050:
解題思路:主要是用到遞推即可。遞推過程:首先分析直線分平面最多多少份: f(1)=2;f(2)=4;f(3)=7;f(4)=11……可知f(n)=f(n-1)+n且f(1)=2.可知f(n)=(1+n)*n/2+1;同理,可將每個折線看成是兩條直線,但是少了一半。因此每一條折線比兩條直線分割的面的部分少2。因此n條折線比2n條直線分割平面形成的部分少2n。所以f(n)=2*n^2-n+1;CP的程式碼:#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
while(n)
{
int m;
cin>>m;
int sum=2*m*m-m+1;
cout<<sum<<endl;
n--;
}
return 0;
}