1. 程式人生 > >dfs 遞迴思想 解決排列組合的一些基礎問題

dfs 遞迴思想 解決排列組合的一些基礎問題

對於搜尋的深度很深或深度不固定的情況,則無法用列舉的方法來設定迴圈巢狀的層數,這時可以考慮用遞迴法來完成搜尋任務。遞迴是一種常用演算法,它是搜尋的另一種實現方式。如果在演算法設計中採用一個函式或過程直接或間接地呼叫它自身來解決問題的方法,則稱該方法為遞迴演算法。遞迴演算法必須要設計好一個或若干個確定的遞迴終止條件。

一......

Sample Input

4 2   //用0,1組合出四個數字來

Sample Output 

0000  0001  0010  0011  0100  0101 

0110  0111  1000  1001  1010 1011 

1100  1101  1110  1111 


#include<stdio.h>

int n,m,ans;
int mat[10];

void solve(int l)
{
    if(l>=n)
    {
        for(int i=0;i<n;++i)printf("%d", mat[i]);
        puts("");
        ans++;
        return ;
    }
    for(int i=0;i<m;++i)
    {
        mat[l]=i;
        solve(l+1);
    }
}

int main()
{
    while(scanf("%d%d", &n, &m)!=EOF)
    {
        ans=0;
        solve(0);
        printf("%d\n",ans);
    }
    return 0;
}


二全組合排列(沒有去重,沒有考慮0的問題)

#include<stdio.h>
#include<string.h>

const int maxn=11;
int n;
int used[maxn];//標記陣列
int mat[maxn];//儲存陣列
int num[maxn];//輸出陣列

void solve(int l)
{
    if(l>=n)
    {
        for(int i=0;i<n;++i)printf("%d", num[i]);
        puts("");
        return;
    }
    for(int i=0;i<n;++i)
    {
        if(!used[i])
        {
            used[i]=1;
            num[l]=mat[i];
            solve(l+1);   //遞迴
            used[i]=0;    //回溯
        }
    }
}

int main()
{
    while(scanf("%d", &n)!=EOF)
    {
        for(int i=0;i<n;++i)
        scanf("%d", mat+i);
        memset(used,0,sizeof(used));
        solve(0);
    }
    return 0;
}
三非重複組合排列(含重複數字時,生成不重複組合排列,並且0也不能放在首位)
#include <cstdio>
#include <cstring>

const int maxn = 10;
int n,v,ans;
int used[maxn],a[maxn],num[maxn];

void push(int v)
{
    for(int i = 0 ; i < ans ; i++)
    {
        if(a[i]==v)
        {
            ++used[i];
            return ;
        }
    }
    a[ans]=v;
    ++used[ans++];  //ans為不重複的數字的個數
    //used[i]儲存的是i出現的次數
}

void solve(int l)
{
    if(l>=n)
    {
        for(int i = 0 ; i < n ; i++)printf("%d",num[i]);
        puts("");
    }
    for(int i = 0 ; i < ans ; i++)
    {
        if(l==0&&a[i]==0)continue;
        if(used[i])
        {
            used[i]--;
            num[l]=a[i];
            solve(l+1);
            used[i]++;
        }
    }
}

int main()
{
    while(scanf("%d", &n)!=EOF)
    {
        memset(used,0,sizeof(used));
        ans=0;
        for(int i=0;i<n;++i)
        {
            scanf("%d", &v);
            push(v);
        }
        solve(0);
    }
    return 0;
}