dfs理解——以出栈方式的字典序为例(对上一个出栈字典序的完善和强化)

笔者认为,dfs的本质在于试验每一方向还原

试验每一方向的含义是:将实际题目中的条件几何化为多个方向,给这些方向赋予优先级(一般采用在dfs函数中写入顺序为优先级,这样比较简单方便),按照优先级的顺序来进行试验,每个节点都有基本相同的方向和优先级的,就可以使用dfs的方式解决。

 

还原:还原要结合试验方向来看。试验方向的终止有几种可能——到达限制边缘,到达转出终点,该节点所有方向已经遍历。当试验方向终止时,我们需要回到上一节点,这一动作我称为回溯。回溯分为两个部分比较容易理解:第一部分是在几何层面上把依托成几何化坐标的条件回到上一坐标,一般我会把这些几何化的条件作为dfs的参数,将条件几何化的目的本身就是为了便于直接回到上一节点。第二部分是还原,也就是一般情况下比较困难的部分,它不像几何参数那么直接,我们需要找到在各种情况下我们所需要的除几何参数以外的变量的上一状况,最容易的方法是在需要还原的变量改变前用另外的变量将原值记录然后在回溯时重新赋回原值。(此处需要特别注意,并不是所有变量都需要还原,需要结合题意找出和每一操作撤销密切相关同时又多半作为变化基础的变量)

 

为了代码的简洁,在有时间充裕的情况下,找到题目的特异性规律可以让还原所需要的变量的过程变得简单明了很多。

 

此处给出普适思路源代码:

复制代码
#include<iostream>
using namespace std;

int n, m;
int a[15], b[15];
int stack[16];
int top = -1;

void dfs(int x, int y){
    if(x == n && y == n){//结束出口,此处到终点 
        for(int i = 0; i<n; i++)
            cout<<a[i]<<" ";
        printf("\n");
        return;
    }

//y放在x前,作用为能上先上,不能上再右,和条件希望得到字典序有关

//入栈和出栈的操作和还原都对top指针有影响,所以x、y操作部分代码各自对top指针有加减   
//栈顶内容是栈的内容的末尾,而回溯后末尾之后的都不要了,所以只要能够找到当时正确的栈顶内容就可以了 (没有回溯的部分不管它的栈原来完整内容是什么,因为我们的a[y]不会受到影响,y之前不会回溯,沿用之前a[y]内容) if(y<n&&y<x){//限制条件,限定关系条件和边缘 a[y] = stack[top];//既是赋值出栈序列又是保存栈顶内容 (因为每个节点都有栈顶,所以不能用单一变量来标识) --top; dfs(x, y+1); ++top; stack[top]=a[y];//还原栈顶内容 } if(x<n){//限制条件,限定关系是x>=y,但是上面的if已经有这个效果故省略,限定边缘 ++top; stack[top]=x+1; dfs(x+1, y); --top; } return; } int main(){ cin >> n; dfs(0, 0); return 0; }
复制代码

 

posted @   silverAugustine  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示