再帰: フィボナッチ数列、指数列挙の再帰的実装、順列列挙の再帰的実装

再帰: O(2^n)

        自分に電話してください

例とコード テンプレート:

フィボナッチ数列

整数 n を入力し、フィボナッチ数列の n 番目の項を見つけます。

0から始まるとすると、0番目の項目は0になります。

データ範囲

0≤n≤39

サンプル

输入整数 n=5 

返回 5
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

int Fibonacci(int n){
		if(n==0) return 0;
        if(n==1) return 1;
	    if(n==2) return 1;
	    return Fibonacci(n-1)+Fibonacci(n-2);
}
int main(){
	int n;
	cin>>n;
	cout<<Fibonacci(n)<<endl;
	return 0;
} 

O(n*2^n)

指数列挙の再帰的実装

1~n の任意の n 個の整数をランダムに選択し、考えられるすべての選択肢を出力します。

入力フォーマット

整数 n を入力します。

出力フォーマット

1 行に 1 つのスキームを出力します。

同じ行内の数値は昇順に並べる必要があり、隣接する 2 つの数値は 1 つのスペースで区切る必要があります。

数値を選択しないスキームの場合は、空白行が出力されます。

この質問にはカスタム バリデータ (SPJ) があり、行間の順序 (異なるスキーム) は任意です。

データ範囲

1≤n≤15

入力サンプル:

3

出力例:


3
2
2 3
1
1 3
1 2
1 2 3

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=15;
int n;
int st[N];
void dfs(int u){
	if(u==n){
		for(int i=0;i<n;i++){
			if(st[i]==1)
				cout<<i+1<<" ";
		}
		cout<<endl;
		return ;
	}
	st[u]=2;
	dfs(u+1);
	st[u]=0;
	 
	st[u]=1;
	dfs(u+1);
	st[u]=0;
}

int main(){
	cin>>n;
	dfs(0);	
	return 0;
}

順列列挙の再帰的実装

1からnまでの整数をn個並べてランダムに順序をシャッフルし、取り得るすべての順序を出力します。

入力フォーマット

整数 n。

出力フォーマット

すべての解を昇順で 1 行に 1 つ出力します。

まず、同じ行にある 2 つの隣接する数字はスペースで区切られます。

次に、2 つの異なる行について、添字に対応する数字を 1 つずつ比較し、辞書順の小さい方が最初にランク付けされます。

データ範囲

1≤n≤9

入力サンプル:

3

出力例:

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

 時間計算量:

                合計 n 層の再帰:

                        最初の層は次のとおりです: O(n)

                           2 番目の層: n 個の分岐があり、各分岐には for ループ、つまり O(n*n) があります。

                           3 番目の層: n*(n-1) 個の分岐があり、各分岐には for ループ、つまり O(n*(n-1)*n) があります。

                            ……

                           レイヤ n (リーフ ノード): n 個あります。ブランチの場合、各ブランチには O(n!*n) の for ループがあります。

                        したがって、合計の時間計算量は次のようになります: n(1+n+n(n-1)+...+n!)

                        (1+n+n(n-1)+...+n!) は次と同等です: (n!+n!/1+n!/(1*2)+n!/(1*2*3) ) +…+n!/(n-1)!+n!/n!); まず、この式は n! より大きく、(n!+n!/1+n!/2+n!) より小さい必要があります。 /4+ ...+n!/2^(n-1)+n!/2^n) つまり 3n!

                        したがって、この質問の時間計算量は O(3n*n!)、つまり O(n*n!) です。

#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=10;
int n,state[N];
bool used[N];
void dfs(int u) {
	if(u>n) {
		for(int i=1; i<=n; i++)
			cout<<state[i]<<" ";
		cout<<endl;
		return ;
	}
	for(int i=1; i<=n; i++) {
		if(!used[i]) {
			state[u]=i;
			used[i]=true;
			dfs(u+1);
			state[u]=0;
			used[i]=false;
		}
	}
}
int main() {
	cin>>n;
	dfs(1);
	return 0;
}

複合列挙の再帰的実装

スコア付き

おすすめ

転載: blog.csdn.net/m0_56501550/article/details/129738242