• 双栈维护之--Hdu4699 editor


    http://acm.hdu.edu.cn/showproblem.php?pid=4699

    题意:简而言之,有5种操作:

    I在光标右边插入一个数

    D删除光标左边的数 ,

    L将光标移动最左边

    R将光标移动到最右边

    Q k 询问k位置以前的最大前缀和

    思路:定义两个栈,一个从前开始,一个从后开始,二者加起来就是整个数列。至于最大前缀和用dp维护一下就好了, dp[i]=(dp[i-1],sum[i]); sum数组里存储的是1~i的和。
    注意:栈为空的情况,不能直接pop

    #include<cstdio>
    #include<queue>
    #include<stack>
    #include<algorithm>
    using namespace std;
    const int inf=-0x3f3f3f3f;//注意
     
     
    int sum[1000006];
    int dp[1000006];//dp[i]表示在前i
     
    int main(){
    	int t;
    	while(~scanf("%d",&t)){
    		memset(sum,0,sizeof(sum));
    		memset(dp,inf,sizeof(dp));//因为dp的值为最大的前缀和,维护最大需要初始化为-inf,但是memset(-inf)会有问题,所以有宏定义的修改
    		stack<int>s1,s2;	
    		int pos=0;//光标当前所指的位置
    		while(t--){
    			getchar();//注意空格
    			char c;
    			scanf("%c",&c);
    			if(c=='I'){
    				int a;
    				scanf("%d",&a);
    				s1.push (a);
    				pos++;//移动光标都要更新一下前缀和和最大前缀和
    				sum[pos]=sum[pos-1]+a;
    				dp[pos]=max(dp[pos-1],sum[pos]);
    			}else if(c=='Q'){
    				int a;
    				scanf("%d",&a);
    				printf("%d
    ",dp[a]);
    			}else if(c=='L'){
    				if(s1.empty())continue;//注意
    				pos--;
    				int b=s1.top ();
    				s1.pop ();
    				s2.push (b);
    			}else if(c=='D'){
    				if(s1.empty())continue;注意
    				s1.pop();
    				pos--;
    			}else if(c=='R'){
    				if(s2.empty())continue;
    				int b=s2.top ();s2.pop();
    				s1.push (b);
    				pos++;
    				sum[pos]=sum[pos-1]+b;
    				dp[pos]=max(dp[pos-1],sum[pos]);
    			}else{
    				int a;
    				scanf("%d",&a);
    				printf("%d
    ",dp[a]);
    			}
    		}
    	}
    }
    

      

  • 相关阅读:
    项目人力资源管理
    以太网交换机
    邮件协议简单学习
    信息系统开发方法
    项目成本管理
    oracle学习笔记002---oracle的体系结构
    007 项目进度管理
    乘法逆元
    RMQ __ST
    中国剩余定理(CRT)
  • 原文地址:https://www.cnblogs.com/cutemush/p/13773951.html
Copyright © 2020-2023  润新知