zoukankan      html  css  js  c++  java
  • 双栈维护之--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]);
    			}
    		}
    	}
    }
    

      

  • 相关阅读:
    txt换行追加写入
    np.unique( )的用法
    生成自己想要的任意颜色的图片
    183. 木材加工
    575. 字符串解码
    364. 接雨水 II
    255. Multi-string search
    433. 岛屿的个数
    591. 连接图 III
    918. 三数之和
  • 原文地址:https://www.cnblogs.com/cutemush/p/13773951.html
Copyright © 2011-2022 走看看