P10334 题解
A_small_WA · · 题解
upd:
一道有意思的单调栈题。
首先,先来分析题意,每个时间可以生产一杯果汁,固定的时间会有人拿走当前最大的一杯果汁,且要求比他期望的大。求榨果汁最少的体积。
可以发现,每杯果汁都要尽量靠后做。
如果有一个人
那么当每个人来取果汁的时间均不同时,就可以做好就取。
否则,如果有
这并不是将剩余
接下来就分析一下代码,可以从后往前看(毕竟需要提前做的果汁一定是从后往前排的)由于
但是后来这种做法被 Hack 了,所以我加了个二分查找,每次找下一个人的时间,预留一些时间给排在队列中的果汁。减少了一些不必要的循环。
Tips:如果您 long long
#include <bits/stdc++.h>
using namespace std;
stack <int> st;
int t[350000],m[350000];
long long ans;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>t[i];
if(t[i]<i){
cout<<-1;
return 0;
}
}
for(int i=1;i<=n;i++){
cin>>m[i];
}
int dw=n;
for(int i=t[n];i>=1;i--){
i=min(i,int(st.size()+t[upper_bound(t+1,t+n+1,i)-t-1]));
//查找下一个人,预留st.size()个空位给将要来的人。
if(t[dw]<i){
//当下一个人还没来取果汁时,就可以先制作后面的
if(st.size()){
ans+=st.top();
st.pop();
}
}else if(t[dw]==i){
//当下一个人已经来取果汁时,就立刻制作他的
if(st.size()) st.push(max(st.top(),m[dw]));
else st.push(m[dw]);
dw--,i++;
}else if(t[dw]>i) dw--,i++;
//当下一个人和上一个人同时取果汁时就要存到栈里提前制作。
}
while(st.size()){
ans+=st.top();
st.pop();
}
cout<<ans;
return 0;
}
这是蒟蒻的第二篇题解,支持一下孩子吧!