用DFS从n个数中选出m个数、全排列

用DFS从n个数中选出m个数

假设从1-12中选出5个不同的数,问有多少种情况。
不考虑每个数的顺序
两种写法,开始点不同
1)第一种DFS的开始点是以1-12中的一个为起点,然后依次考虑后面的数。
2)第二种是从0开始,0相当于一个虚节点,然后依次考虑后面的数。
一:

在这里插入图片描述

#include <bits/stdc++.h>
#include <algorithm>
#include <cmath>
#define mod 1000000007
#define ll long long

using namespace std;

int a[15];
int dis[4][2] = {-1,0,1,0,0,-1,0,1};
int ans = 0;
void dfs(int x,int l)
{
	if(l == 5){
		for(int i = 1; i <= 12; i++){
			if(a[i]) cout << i << " ";
		}ans++;
		cout << "\n";
		return;
	}
	for(int i = x + 1; i <= 12; i++){
		if(!a[i]){
    		a[i] = 1;
    		dfs(i,l+1);
    		a[i] = 0;
		}
	}
}
int main()
{
	for(int i = 1; i <= 12; i++){
		a[i] = 1;
    	dfs(i,1);
    	a[i] = 0;
    }
	cout << ans;
    return 0;	
} 

二:
在这里插入图片描述

#include <bits/stdc++.h>
#include <algorithm>
#include <cmath>
#define mod 1000000007
#define ll long long

using namespace std;

int a[15];
int dis[4][2] = {-1,0,1,0,0,-1,0,1};
int ans = 0;
void dfs(int x,int l)
{
	if(l == 5){
		for(int i = 1; i <= 12; i++){
			if(a[i]) cout << i << " ";
		}ans++;
		cout << "\n";
		return;
	}
	for(int i = x + 1; i <= 12; i++){
		if(!a[i]){
    		a[i] = 1;
    		dfs(i,l+1);
    		a[i] = 0;
		}
	}
}
int main()
{
    dfs(0,0);
	cout << ans;
    return 0;	
} 

考虑顺序:如果n=m,就是全排列

#include <bits/stdc++.h>
#include <algorithm>
#include <cmath>
#define mod 1000000007
#define ll long long

using namespace std;

int a[15],b[15];
int dis[4][2] = {-1,0,1,0,0,-1,0,1};
int ans = 0;
void dfs(int x,int l)
{
	b[l] = x;
	if(l == 3){
		for(int i = 1; i <= l; i++)
		    cout << b[i] << " ";
		ans++;
		cout << "\n";
		return;
	}
	for(int i = 1; i <= 3; i++){
		if(!a[i]){
    		a[i] = 1;
    		dfs(i,l+1);
    		a[i] = 0;
		}
	}
}
int main()
{
	for(int i = 1; i <= 3; i++){
		a[i] = 1;
		b[1] = i;
        dfs(i,1);
        a[i] = 0;
    }
	cout << ans;
    return 0;	
} 

蓝桥杯2016年决赛

题目

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stack>
#include <queue>
#include <string.h>
#include <cmath>
#include <bitset>
#include <set>
#include <map>
#include <list>
#define ll long long
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const ll ds = 1e15+7;
const double p = 3.141592653589793238462643383;

using namespace std;

int ans = 0;
int a[4] = {2,3,5,8};
int b[4] = {1,4,6,7};
int vis[55] = {0};

void dfs(int sum[][2],int l)
{
	if(l >= 4){
		int sum1,sum2;
		sum1 = sum2 = 0;
		for(int i = 0; i < 4; i++){
			sum1 += sum[i][0]*sum[i][0];
			sum2 += sum[i][1]*sum[i][1];
		}
		if(sum1 == sum2){
			ans++;
			return;
		}
	}
	for(int i = 0; i < 4; i++){
		for(int j = 0; j < 4; j++){
			if(!vis[i]){
				sum[i][0] = a[i]*10+b[j];
				sum[i][1] = b[j]*10+a[i];
				vis[i] = 1;
				dfs(sum,l+1);
				vis[i] = 0;
			}
		}
	}
}

int main()
{
	int num[5][2];
	dfs(num,0);
	cout << ans/24;
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值