题解:P11325 【MX-S7-T3】「SMOI-R2」Monotonic Queue
怎么大家都是 dp,来一个贪心(?)题解。
题意
有点复杂,自己看题面。
最终 sum 是所有通过右边弹出的元素的
思路
下文中,称 deque 的 front 为左边/前面。
观察题面中的代码,发现其实不需要管具体的
再做转化,变成选择一个
先考虑如何算
然后观察 pop_front 操作起到了什么作用。发现它相当于每次 push 完后,删去单调栈的一个前缀(不能删空)。那么我们可以直接把这个操作放到 push 操作的弹栈过程中,每次从后面弹出时(除了每轮弹出的第一个元素,这是因为不能删空),你可以放弃这次弹出,改为直接把栈删空。
此后由于不存在 pop_front 操作,直接称 pop_back 为弹出。
之后我们可以开始贪了。每次弹出一个元素(设之为
模拟这个过程即可。
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,c[500005],ans,a[500005],s;
deque<int>q;//用 stack 就行了
signed main(){
cin>>n;
for(int i=1;i<=n;i++) scanf("%lld",&c[i]);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
int op=0;
while(q.size()&&a[q.back()]<a[i]){
int x=q.back();
q.pop_back();
if(op){
if(c[x]>0) s+=c[x];//一定赚
else if(q.size()) c[q.back()]+=c[x];//如果弹出 q.back(),那么弹出 x,否则清空。
}
else s+=c[x],op=1;// 这是第一次弹出
}
q.push_back(i);
ans=max(ans,s);
}
cout<<ans;
}