递归与枚举 CH0301 CH0302 CH0303

1.递归实现指数型枚举

从1——n这n(n<20)个数中随机选取任意多个。输出所有可能的方案,

等价于每个整数可以选或者不选,所有的方案为2^n种,DFS思想,选与不选,选了之后要回溯

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
const int MAXN=1e4+5;
int n;
vector<int> chosen; //被选择的数
void calc(int x)
{
    if(x==n+1){
        for(int i=0;i<chosen.size();i++)
            printf("%d ",chosen[i]);
       printf("\n");
        return ;
    }
    //不选x
    calc(x+1); //求解子问题
    //选x
    chosen.push_back(x); //记录x被记录
    calc(x+1);  //求解子问题
    chosen.pop_back();//还原
}

int main()
{
    scanf("%d",&n);
    calc(1);
}

2.递归实现排列型枚举

从1——n这n个整数中随机选出m(0<=m<=n<20)个,,输出所有可能的方案

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
const int MAXN=1e4+5;
int n,m;
vector<int> chosen; //被选择的数
void calc(int x)
{
    if(chosen.size()>m||chosen.size()+(n-x+1)<m){
        return ;
    }
    if(x==n+1){
        for(int i=0;i<chosen.size();i++)
            printf("%d ",chosen[i]);
       printf("\n");
        return ;
    }

    //选x
    chosen.push_back(x); //记录x被记录
    calc(x+1);  //求解子问题
    chosen.pop_back();//还原
      //不选x
    calc(x+1); //求解子问题
}

int main()
{
    scanf("%d%d",&n,&m);
    calc(1);
}

3.递归实现排列型枚举

把1——n这n个整数排列成一行之后随机打乱,输出所有可能的次序,

全排列问题,所有的可能为N!种,在每次递归中,尝试把每个可用的数作为数列中下一个数,求解n-1个整数安装任意次序排列的这个规模更小的问题

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
const int MAXN=1e4+5;
int n;
int order[20]; //按顺序依次记录被选择的整数
bool chosen[20];  //标记被选择的整数
void calc(int k)
{
    if(k==n+1){
        for(int i=1;i<=n;i++)
            printf("%d ",order[i]);
        printf("\n");
        return ;
    }
    for(int i=1;i<=n;i++){
        if(chosen[i])
          continue;
        order[k]=i;
        chosen[i]=i;
        calc(k+1);
        chosen[i]=0;
        order[k]=0;
    }
}
int main()
{
    scanf("%d",&n);
    calc(1);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/deepseazbw/article/details/81179485