DFS深度优先搜索--全排列 和组合问题求解

全排列:

从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。

公式:全排列数f(n)=n!(定义0!=1)

1.1

//输入n  将1-n的数字进行全排列
#include<iostream>
using namespace std;
int n;
int num[100];
bool  vis[100];
int cnt = 0;
int ans;
void dfs(int i) {
	if (i == n + 1) {
		ans++;
		for (int i = 1; i <= n; i++) {
			cnt++;
			cout << num[i];
			if (cnt % n == 0) {
				cout << endl;
			}
		}
		return;
	}
		for (int k = 1; k <= n; k++) {
			if (vis[k] == false) {
				vis[k] = true;
				num[i] = k;
				dfs(i + 1);
				vis[k] = false;
			}

		}

	



}
int main() {
	cin >> n;
	
	dfs(1);
	cout << "ans:" << ans << endl;
	return  0;
}

 

/  /    1.2     从n个数中选k个数全排列,从第一个数字开始遍历k个数字 if cnt ==3  输出

排列组合

#include<iostream>
using namespace std;
int n, k;//从n个数中取k个数
int cnt = 0;//统计答案次数
int count1 = 0;//换行使用
int num[100]={0};
bool  vis[100]={false};
int ans = 0;
//从n个数中选k个数全排列,从第一个数字开始遍历k个数字 if cnt ==3  输出排列组合
void dfs( int  cnt) {

	if (cnt == k +1) {
		ans++;
		for (int j = 1; j <= k; j++) {
			count1++;
			cout << num[j];
			if (count1 % k== 0) {
				cout << endl;
			}
				
		}
		return;
	}

	for (int t = 1; t <= n; t++) {
		if (vis[t] == false ) {
			num[cnt] = t;
			vis[t] = true;
			dfs( cnt + 1);
			vis[t] = false;
		}
	}
}



int main() {
	cin >> n >> k;
	
	dfs( 1);
	cout << "ans:" << ans;
	return  0;
}

 

 

2.从n个不同元素中,任取m(m≤n)个元素并成一组,叫做从n个不同元素中取出m个元素的一个组合;从n个不同元素中取出m(m≤n)个元素的所有组合的个数,叫做从n个不同元素中取出m个元素的组合数。

中文名: 组合数

.组合问题:在全排列的基础上加上  一个限制条件 输出 数组num【i】中的后一个数比前一个数要大

#include<iostream>
using namespace std;
int n, k;//从n个数中取k个数
int cnt = 0;//统计答案次数
int count1 = 0;//换行使用
int num[100]={0};
bool  vis[100]={false};
int ans = 0;
//从n个数中选k个数全排列,从第一个数字开始遍历k个数字 if cnt ==3  输出排列组合
void dfs( int  cnt,int last) {

	if (cnt == k +1) {
		ans++;
		for (int j = 1; j <= k; j++) {
			count1++;
			cout << num[j];
			if (count1 % k== 0) {
				cout << endl;
			}
				
		}
		return;
	}

	for (int t = 1; t <= n; t++) {
		if (vis[t] == false && t > last) {//条件t>last
			num[cnt] = t;
			last = t;
			vis[t] = true;
			dfs( cnt + 1,t);
			vis[t] = false;
		}
	}
}



int main() {
	cin >> n >> k;
	
	dfs( 1,0);//cnt 从1到 k+1;
	cout << "ans:" << ans;
	return  0;
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值