遞迴和遞推總結

HowieLee59發表於2019-01-24

 

 

1.Acwing 92  遞迴實現指數型列舉

從 1~n 這 n 個整數中隨機選取任意多個,輸出所有可能的選擇方案。

輸入格式

輸入一個整數n。

輸出格式

每行輸出一種方案。

同一行內的數必須升序排列,相鄰兩個數用恰好1個空格隔開。

對於沒有選任何數的方案,輸出空行。

本題有自定義校驗器(SPJ),各行(不同方案)之間的順序任意。

資料範圍

1≤n≤151≤n≤15

輸入樣例:

3

輸出樣例:


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

 

/*
    因為數字是連續的,所以可以使用位運算來做,這樣的話總共可以產生2^n個數,兩次dfs的意思是進行疊    
  加,這樣的話就可以產生唯一併且有序的陣列了。
*/
#include<iostream>

using namespace std;

int n;

void dfs(int u,int state){
    if(u == n){
        for(int i = 0 ; i < n ;i++){
            if(state >> i & 1){//判斷state當前第i位上是不是1 
                cout << i + 1 << ' ';
            }
        }
        cout << endl;
        return ;
    }
    dfs(u+1,state);//遍歷所有的數
    dfs(u + 1, state | 1 << u);//進行疊加 
}

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

 

2.Acwing 93  遞迴實現組合型列舉

從 1~n 這 n 個整數中隨機選出 m 個,輸出所有可能的選擇方案。

輸入格式

兩個整數 n,mn,m ,在同一行用空格隔開。

輸出格式

按照從小到大的順序輸出所有方案,每行1個。

首先,同一行內的數升序排列,相鄰兩個數用一個空格隔開。

其次,對於兩個不同的行,對應下標的數一一比較,字典序較小的排在前面(例如1 3 5 7排在1 3 6 8前面)。

資料範圍

n>0n>0 ,
0≤m≤n0≤m≤n ,
n+(n−m)≤25n+(n−m)≤25

輸入樣例:

5 3

輸出樣例:

1 2 3 
1 2 4 
1 2 5 
1 3 4 
1 3 5 
1 4 5 
2 3 4 
2 3 5 
2 4 5 
3 4 5 
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int n, m;

void dfs(int u, int s, int state)//引入s來控制回溯
{
    if (s == m)
    {
        for (int i = 0; i < n; i ++ )
            if (state >> i & 1)
                cout << i + 1 << ' ';
        cout << endl;
        return;
    }
    if (u == n) return;

    for (int i = u; i < n; i ++ )
    {
        dfs(i + 1, s + 1, state + (1 << i));//控制回溯,最大的是2^n,則通過dfs完全可以模擬
    }
}

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

3. Acwing 94  遞迴實現排列型列舉

把 1~nn 這 nn 個整數排成一行後隨機打亂順序,輸出所有可能的次序。

輸入格式

一個整數n。

輸出格式

按照從小到大的順序輸出所有方案,每行1個。

首先,同一行相鄰兩個數用一個空格隔開。

其次,對於兩個不同的行,對應下標的數一一比較,字典序較小的排在前面。

資料範圍

1≤n≤91≤n≤9

輸入樣例:

3

輸出樣例:

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>

using namespace std;

int n;
vector<int> path;

void dfs(int u,int state){
    if(u == n){
        for(auto x : path){
            cout << x << ' ';
        }
        cout << endl;
        return ;
    }
    for(int i = 0 ; i < n ;i++){
        if(!(state >> i & 1)){
            path.push_back(i + 1);
            dfs(u+1,state+(1<<i));//通過dfs進行新增
            path.pop_back();//回溯的點
        }
    }
}

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

 

 

相關文章