暴力枚举(搜索)

本文介绍了如何通过up主的详细讲解,掌握全组合和全排列问题的解决方法,重点讲解了递归回溯算法的应用,以及如何通过剪枝优化全组合算法。作者提供了C++代码示例以演示这两种经典问题的求解过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个很喜欢的up主,讲的很仔细,问题类型也很全面,推荐看一下。
学习视频
写在前面:
我认为所有暴力的基础是全组合和全排列,就是要把数据的所有可能性罗列出来然后通过一个一个验证来决定是否符合题目要求,所以学好全排列和全组合是暴力基础中的基础。
对于全组合和全排列的求解,最常用的算法就是递归回溯算法,对于每个算法我们都可以画一个递归搜索树,进行dfs,然后这个树的叶子节点就是我们想要的部分。
在这里插入图片描述

全组合

全组合的逻辑是,下一个选的数的下标一定要比下一个下标大,简单的比如只选两个,可以用简单的双指针for循环嵌套来解决
在这里插入图片描述

1.普通全组合

#include<iostream>
#include<vector>
using namespace std;
int n=5,r=3;//从5个数据里,选择3个组成组合
vector <int> result; //将数据放入result中
//全组合,给定两个数n,r n表示数据的长度,r表示组合的长度 
void dfs1(int startIndex){//startIndex表示,下一个数字要从startIndex开始选择
//如果result的长度等于r则表示递归结束
	if(result.size()==r){
		for(int i=0;i<r;i++){
			cout<<result[i]<<" ";
		}
			cout<<endl; 
		return;
	}else{//单次循环
		for(int i=startIndex;i<n;i++){
			result.push_back(i+1);
//这里表示下个数,要从原数组的那个位置开始选,很明显是当前放入元素的下一个位置
			dfs1(i+1);
			//回溯,撤销操作
			result.pop_back();
		}
	}
}
int main(){
//从0下标开始选
	dfs1(0);
	return 0;
}

2.全组合的剪枝
此时i从0开始
在这里插入图片描述
剪支肯定是有效率提升的,但是提升的有限,也有可能是我测试的有问题
总结
对于全组合来说终止条件是result数组的长度等于r(给定数量)否则我们就遍历startIndex一直到最后一个元素,循环放入元素,一次结束的时候回溯即可。特别的如果剪支的情况下,当只有当i<=result.size+n-k才可以,剩下的部分可以直接被剪去,i从startindex变化到result.size+n-k;(全组合选数,一定是从当前放入结果数组中的后序元素开始选)

全排列

其实想到了result.size其实就好好写
全排列的逻辑是已经选过的不能再选,等到数组长度达到要求就可以收获啦
在这里插入图片描述

#include<iostream>
#include<vector>
#include<iomanip>
using namespace std;
int n;
vector <int> used;
vector <int> result;
//index从0开始表示result要放下标为index 
void dfs(){
	if(result.size()==n){
		for(int i=0;i<result.size();i++){
			cout<<setw(5)<<result[i];
		}
		cout<<endl;
		return;
	}else{
		for(int i=0;i<n;i++){
			if(!used[i]){
				result.push_back(i+1);//对应数组元素 
				used[i]=1;
				dfs();
				result.pop_back();
				used[i]=0;
			}
		}
	}
}
int main(){
    cin>>n;
    used.assign(n,0);
	 dfs();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值