DFS模板

在网上找到了一个神奇的网站。算法笔记
DFS是一种十分重要也中用的算法。
对于大多数问题,只要用了DFS,都可以解决。
以下是我总结出来的关于它的一些思想。

这是一个十分重要的框架,但只能重复搜索。

Type solution[MAXN]; //保存解的数组
void dfs(int i) { //当前搜索第i个阶段
if (到达边界) 
{
	检验solution是否是合法解;
	记录解或者输出解;
	return;
}
for (第i个阶段的所有选项)
	if (j是合法选项)
	{
		solution[i] = j; //保存当前选项;
		dfs(i+1); //递归到下一阶段
	}
}

下列是两种对上面问题的解决方法,但只能针对答案不重复。

函数法

bool check(int i,int j)//判断此元素在当前答案里是否重复
{
	for(int k=0;k<i;k++)
		if(ans[k]==j)return 0;
	return 0;
}
for(int j=1;j<=k;j++)
	if(check(i,j))
	{
		ans[i]=j;
		dfs(i+1);
	}

数组法(非常实用)

int vis[];
void dfs(int x)
{
	if(超出范围)
		return 0;
	for(枚举所有元素)
		if(!vis[j])
		{
			vis[i]=1;ans[x]=j
			dfs(x+1);
			vis[i]=0;//回溯
		}
}

对于重复元素的排列。
数组法是一个实用的方法:把元素数量存下来,再判断是否超出。
而数组在对于大多数参数都能找出并判断。
而记忆化搜索就是建立在数组法的基础上的。
只需判断一下价值大小就可以了。例题

最后,介绍一个关于排列的函数。

#include<cstdio>
#include<algorithm>
using namespace std;//调用STL函数
#define M 10
int a[M],cnt;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    sort(a+1,a+1+n);//生成最小排列(从小到大排序)
    do
    {
        printf("%d:",++cnt);
        for(int i=1;i<n;i++)
            printf("%d ",a[i]);
        printf("%d\n",a[n]);
    }while(next_permutation(a+1,a+1+n));
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值