寒假之(遞迴與分治)

2021-09-09 09:09:38 字數 2394 閱讀 1023

遞迴的思想就把問題簡單化,分為更小的子問題,乙個乙個去解決,每種情況之間還會回溯,分出所有的情況,對於一些資料量小的問題,可以用全遞迴,對於資料量大的,就可以用dp(記憶化搜尋)(現在不提)。窮盡搜尋時可以考慮遞迴演算法。具有一定的回退性。

分治與遞迴是分不開的,將問題分為區域性問題。遞迴求解區域性為。將區域性問題」整合「,解決原問題。

看道題目:

編寫乙個程式,讀取n個元素和整數m的序列a,如果可以通過在a中新增元素來生成m,則輸出「yes」,否則輸出「no」。乙個元素只能使用一次。              

在每個問題中都包含mi的順序a和q問題。              

輸入              

在第一行給出n。在第二行中,給出n個整數。第三行中給出了q。然後,在第四行中,給出q整數(mi)。              

輸出              

對於每個問題mi,列印「是」或「否」 

5

1 5 7 10 21

82 4 17 8 22 21 100 35

no

noyes

yesyes

yesno

no

首先看題,不知道怎麼下手,怎麼用迴圈把所有的情況列舉出來,再來判斷?有點困難,題解用遞迴實現窮舉,將情況全部都判斷一遍,遞迴有個好處,可以回溯返回上一層的情況,接著改變狀態,再判斷一次,看看能否滿足條件。第乙個數列的每個資料都有兩種狀態,可以選,也可以不選。於是,遞迴的這個方程就是將所有情況都考慮進去,就可以實現窮舉所有情況。(需要將所有情況都考慮進去)。

如果選擇當前資料,就 當前的滿足條件的和(每次遞迴都會不一樣的,狀態不一樣,類似於狀態轉移方程,每次的狀態都會改變)。

**就會出來:

#include#includeusing namespace std;

#include#include#include#include#include#include#includeconst int maxn=100005;

typedef long long ll;

int n;

int a[maxn];

int solve(int i,int m)

int main()

{ int q,m,i;

cin>>n;

for(i=0;i>a[i];

cin>>q;

for(i=0;i>m;

if(solve(0,m))

cout<<"yes"《用1來表示被選中,0表示沒被選中。solve(i+1,m) || solve(i+1,m-a[i])  是兩種狀態,可以選,也可不選,窮盡搜尋將所有情況考慮進去。

放蘋果 poj 1664 

description

把m個同樣的蘋果放在n個同樣的盤子裡,允許有的盤子空著不放,問共有多少種不同的分法?(用k表示)5,1,1和1,5,1 是同一種分法。

input

第一行是測試資料的數目t(0 <= t <= 20)。以下每行均包含二個整數m和n,以空格分開。1<=m,n<=10。

output

對輸入的每組資料m和n,用一行輸出相應的k。

sample input

17 3

sample output

同樣採取 遞迴窮盡搜尋的方法,來得到所有的可能, 這就需要將所有的分的方法都要想到,大致可以分為 1.至少有乙個空盤子 2.沒有空盤子。如果盤子數量大於蘋果的數量,就可以把多餘的盤子扔掉(因為沒有用)。思路大概是這個樣子。  第一種情況,可以有盤子為空的情況,那就在別的盤裡面多放幾個,盤子數量減減,直到盤子就為乙個的時候,這就到達終點了,將所有蘋果全放到這乙個盤子裡面。2.第二種情況就是,沒有盤子為空的,所有盤子都有蘋果,那就把餘下的蘋果再按照這幾個盤子再去分,就會達到每個盤子數量不一樣的情況,直到分的蘋果最後為0 的時候,說明蘋果一遍一遍的  以乙個為單位放到每個盤子情況結束。

因為遞迴有回溯的功能,這兩種情況會不斷地重疊,交叉,來達到窮舉的效果。

想到這裡,**基本上就會出來了:

**:#include#include#include#includeconst int maxn=1000100;

using namespace std;

typedef long long ll;

const int mod=1000000000;

ll fun(ll m,ll n)

{ if(m==0||n==1)

return 1;

if(m>t;

ll m,n;

while(t--)

{ cin>>m>>n;

cout《基本上的思想就是這樣子。但是分治與遞迴的題型會很多。就在訓練題中乙個乙個遇見吧。

遞迴與分治練習題目 hdu 4643 2050 poj 2586 

分治與遞迴

分治與遞迴 分治法的設計思想是,將乙個難以直接解決的大問題,分割成一些規模較小的相同問題,以便各個擊破,分而治之。對這k個子問題分別求解。如果子問題的規模仍然不夠小,則再劃分為k個子問題,如此遞迴的進行下去,直到問題規模足夠小,很容易求出其解為止。將求出的小規模的問題的解合併為乙個更大規模的問題的解...

遞迴與分治

一 1 求階乘 int factorial int n 2 fibonacci函式 int fibonacci int n 3 全排列 1 字串的全排列 主函式見 2 int permutation char a,int k,int m permutation arr,0,n 1 return 0 ...

遞迴與分治

fibonacci數列 無窮數列1,1,2,3,5,8,13,21,34,55,稱為fibonacci數列。它可以遞迴地定義為 第n個fibonacci數可遞迴地計算如下 int fibonacci int n 編寫完整的主函式,分別記錄利用上述遞迴函式求第47,48,49,50,51,52個fib...