#动态规划,栈,对顶栈#hdu 4699 Editor

题目

有五种操作
I I I x : x: x:在当前光标处插入一个整数x,插入后光标移动到x之后
D : D: D:删除光标前的一个整数
L : L: L:光标向左移动一个位置
R : R: R:光标向右移动一个位置
Q Q Q x : x: x:在位置 x x x之前的最大的前缀和


分析

这样的操作不难想到对顶栈的方法,而栈 A A A表示光标处(栈顶)至开头(栈底)的子序列,栈 B B B表示光标处至末尾的子序列, s u m sum sum表示前缀和, f f f表示最大的前缀和(动态规划)
当操作 I I I x x x

  1. x x x插入栈 A A A
  2. s u m [ c u r s o r ] = s u m [ c u r s o r − 1 ] + x sum[cursor]=sum[cursor-1]+x sum[cursor]=sum[cursor1]+x
  3. f [ c u r s o r ] = m a x ( f [ c u r s o r − 1 ] , s u m [ c u r s o r ] ) f[cursor]=max(f[cursor-1],sum[cursor]) f[cursor]=max(f[cursor1],sum[cursor])

当操作 D D D时把 A A A的栈顶弹出
当操作 L L L时把 A A A的栈顶插入 B B B并弹出 A A A的栈顶
当操作 R R R

  1. B B B的栈顶插入 A A A并弹出 B B B的栈顶
  2. s u m [ c u r s o r ] = s u m [ c u r s o r − 1 ] + x sum[cursor]=sum[cursor-1]+x sum[cursor]=sum[cursor1]+x
  3. f [ c u r s o r ] = m a x ( f [ c u r s o r − 1 ] , s u m [ c u r s o r ] ) f[cursor]=max(f[cursor-1],sum[cursor]) f[cursor]=max(f[cursor1],sum[cursor])

当操作 Q Q Q x x x时,直接输出 f [ x ] f[x] f[x]


代码

#include <cstdio>
#include <stack>
using namespace std;
stack<int>a; stack<int>b; int n,num,sum[1000001],f[1000001];
int in(){
	int ans=0,f=1; char c=getchar();
	while ((c<48||c>57)&&c!='-') c=getchar();
	if (c=='-') c=getchar(),f=-f;
	while (c>47&&c<58) ans=ans*10+c-48,c=getchar();
	return ans*f;
} 
int main(){
	while (scanf("%d",&n)==1){//多组数据
		while (a.size()) a.pop();//清空栈
	    while (b.size()) b.pop();
		f[0]=-99999999; sum[0]=0; num=0;//f初始很小的数
	    while (n--){
		    char c=getchar(); 
		    while (c<65||c>91) c=getchar(); //保险起见
		    if (c=='I'){//操作I
			    int x=in();
			    a.push(x);
			    sum[++num]=sum[num-1]+a.top();//更新前缀和
			    f[num]=max(f[num-1],sum[num]);//dp
		    }
		    else if (c=='D'){
			    if (!num) continue;//注意勿越界
				num--,a.pop();
		    }
		    else if (c=='L') {
		    	if (!num) continue;
		    	num--,b.push(a.top()),a.pop();
		    }
		    else if (c=='Q') printf("%d\n",f[in()]);
		    else{
		    	if (b.empty()) continue;
			    a.push(b.top()); b.pop();
			    sum[++num]=sum[num-1]+a.top();
			    f[num]=max(f[num-1],sum[num]);
		    }
	    }
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值