题意
有n天,每天必须进行两个操作中的一种:买一股股票,或者卖一股股票。第i天股票的价格为a[i],一开始没有股票,卖股票的时候手上至少要有一股股票,问最后的最大利润是多少。可以是负数。
n
≤
2
e
5
n \le 2e5
n≤2e5
解法
贪心:首先考虑一种策略,奇数天买,偶数天卖,然后不断调整这个策略使其变优,考虑对卖的价值维护一个小根堆,如果某奇数天卖更划算,就把之前卖的价格最小的那一天改成买。(对某一天的反悔操作就是选择另一种操作)。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
#define int long long
inline int read(){
char c=getchar();int t=0;
while(!isdigit(c)){c=getchar();if(c==EOF)break;}
while(isdigit(c)){t=(t<<3ll)+(t<<1ll)+1ll*(c^48);c=getchar();if(c==EOF)break;}
return t;
}
int n,a[maxn];
priority_queue<int,vector<int>,greater<int> > q;
signed main(){
//freopen("2.in","r",stdin);
//freopen("2.out","w",stdout);
//scanf("%lld",&n);
n=read();
for(int i=1;i<=n;i++){
//scanf("%lld",&a[i]);
a[i]=read();
}
int alfa=-a[1];
for(int i=2;i<=n;i++){
int x=a[i];
if(i%2==0){
alfa+=x;q.push(x);
}
else{
if(q.empty())continue;
int y=q.top();
if(x>y){
alfa+=x-y*2;
q.pop();q.push(x);
}
else{
alfa-=x;
}
}
}
printf("%lld\n",alfa);
return 0;
}
吐槽
由于在某OJ上,这道题用快速读入会出现TLE的情况,数据结尾应该是没有其它字符,所以快读要加特判EOF,换成scanf也可以.