AcWing 129. 火车进栈(dfs搜索 出栈顺序)

33 篇文章 1 订阅
31 篇文章 0 订阅

在这里插入图片描述
在这里插入图片描述

题意:

若一个栈的输入序列1、2、...、n ,求其可能的出栈顺序,并输出前20种方案。

思路:

我们可以将搜索中的每一个状态用三者来表示:state1(已经出栈的答案序列,用vector存),state2(还在栈中的序列,用一个stack存),state3(还未进栈的序列,直接用一个指向 即将入栈元素 的指针变量表示,因为未进栈的车是有序的)。

我们实际操作只有两种

  • op1:车栈state2弹出栈顶元素并加入state1答案序列

  • op2:将state3所指向的元素压入state2车栈

由于考虑到字典序的原因我们可以 先递归枚举op1递归枚举op2,因为op1表示 出栈,出栈的数必定比进栈的数小(维持字典序的核心)。

直到把所有n个数全部弹出,此为边界情况,输出一种方案。

此外,由于题目要求输出前20种方案,我们设置一个全局变量cnt=20,每输出一个方案就减1,当减到0时就return

2675_cb27c09241-1.png

时间复杂度:

O(2^N)

(每一步可以有两种操作,n个元素复杂度就是2^nn的数据范围较小,n<=20,大约是1e6

代码:

#include<bits/stdc++.h>

using namespace std;

int n;
   //三者共同维护深搜过程中的每个状态
vector<int> state1;   //答案序列
stack<int> state2;   //车栈
int state3 = 1;   //相当于一个指向 即将入栈元素 的指针,初始为1,后续不断加一
int cnt = 20;

void dfs()
{
        if(!cnt){
                return ;   //如果输出的方案满20个就直接return 
        }else if(state1.size()==n){   //当答案序列大小满n个元素时 输出一组方案
                for(int i=0;i<n;++i) cout<<state1[i];
                cout<<endl;
                --cnt;
                return ;
        }   //分支一:车栈state2弹出栈顶元素并加入state1答案序列
        if(state2.size()){   //车栈不空我们才进行弹出操作
                state1.push_back(state2.top()), state2.pop();
                dfs();
                state2.push(state1.back()), state1.pop_back();   //恢复现场方便回溯查找其他方案
        }   //分支二:将state3所指向的元素压入state2车栈
        if(state3<=n){   //保证state3指针不出界
                state2.push(state3), ++state3;
                dfs();
                state2.pop(), --state3;
        }
}

int main()
{
        cin>>n;
        dfs();

        return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值