栈的经典运用

本文介绍了对顶栈在AcWing题目中的应用,包括火车进栈和火车进出栈问题的解决方案。通过 dfs 和01序列转换,解决不同场景下的问题,并探讨了如何优化算法以达到O(1)的复杂度。同时,提到了直方图中最大矩形、城市游戏的二维单调栈解法以及括号序列和中缀表达式的计算问题。
摘要由CSDN通过智能技术生成

AcWing 128.编辑器
话说这题要拿80还是挺简单的,我居然都可以想到对顶栈的办法。
本题参考动态中位数的对顶堆思想,很容易想到以光标为分界线,将已有的序列划分别划入两个栈中。我们不妨将这种方法命名为“对顶栈”。
前面4个操作的实现相当简单,但是最后一个略显困难。当然,我们很容易想到一种暴力枚举的方法如下:

	while(Q--){
   
      	char c;
       	cin>>c;
        if(c=='I'){
   
            int x;
            cin>>x;
            stk2[++top2]=x;
        }
        if(c=='D'){
   
            if(top2){
   
                top2--;
            }
        }
        if(c=='L'){
   
            if(top2){
   
                stk1[++top1]=stk2[top2];
                top2--;
            }
        }
        if(c=='R'){
   
            if(top1){
   
                stk2[++top2]=stk1[top1];
                top1--;
            }
        }
        if(c=='Q'){
   
            int x;
            cin>>x;
            int ans=0,zf=0;
            for(int i=1;i<=min(top2,x);i++){
   
                if(stk2[i]>0 || i==1){
   
                    if(zf+stk2[i]>0 || i==1){
   
                        ans+=zf+stk2[i];
                        zf=0;
                    }
                    else zf+=stk2[i];
                }
                else{
   
                    zf+=stk2[i];
                }
            }
            cout<<ans<<endl;
        }
    }

这种方法当然不够优秀,只能拿到80pts,所以我们要尝试优化,将所有操作的复杂度提升至O(1)。那么,通过思考可知:新加入一个数以及向右移动光标时需要更新答案。我们不妨用数组f[i]来存储答案,询问时直接输出f[k]即可。而f数组的求法也很简单,见代码。

 		if(c=='I'){
   
            int x;
            scanf("%d",&x);
            stk2[++top2]=x;
            if(x+sum[top2-1]-f[top2-1]>0 || top2==1){
   
                f[top2]=x+sum[top2-1];
            }
            else f[top2]=f[top2-1];
            sum[top2]=x+sum[top2-1];//sum是前缀和数组
        }
        if(c=='R'){
   //两处代码完全相同
            if(top1){
   
                int x=stk1[top1];
                stk2[++top2]=x;
                top1--;
                if(x+sum[top2-1]-f[top2-1]>0 || top2==1){
   
                    f[top2]=x+sum[top2-1];
                }
                else f[top2]=f[top2-1];
                sum[top2]=x+sum[top2-1];
            }
        }

总结:“对顶”数据结构适合维护一个有序的序列,支持删除、加入、在线询问等操作。要视具体情况正确使用不同的结构。

1.AcWing 129.火车进栈

本题数据范围较小,又是要输出方案,必然想到用dfs。那么此处的dfs较为特殊,是每次有两种选择的dfs(每次可以选择将栈顶的数出栈或者是将下一个数进栈),那么代码就应当写成每次递归只进行一次操作的样子,而不是循环多次操作。代码如下:

#include<iostream>
using namespace std;
const int N=25;
int stack[N],cnt,top,ans[N],m;
int n;
void dfs(int x){
   
    if(x==n+1){
   
        cnt++;
        if(cnt>20) return;
        for(int i=
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值