hdu4699(对顶栈模拟+简单dp)

1 篇文章 0 订阅

链接: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\n",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\n",dp[a]);
			}
		}
	}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值