题目:http://codeforces.com/contest/867/problem/E
题意:模拟股票操作,每天只能买一只股票或者卖一只股票或者什么也不做,求最大利润。
题解:仔细想想是非常简单的一个贪心问题,理解为连续的多次贪心买入卖出可以合并为一次的买入卖出,且值为最优。只需要用一个最小堆每次寻找前面的最小且没有被标记为购买点的值即可。如果自己为最小值,continue。如果那个值没有被选过,为买入点,pop。如果那个值被选为了售出的点,那么取消售出的标记,把当前点标记为售出点,利润直接加为和堆顶的差值。
#include<bits/stdc++.h> #define pii pair<int, int> #define mod 1000000007 #define mp make_pair #define pi acos(-1) #define eps 0.00000001 #define mst(a,i) memset(a,i,sizeof(a)) #define all(n) n.begin(),n.end() #define lson(x) ((x<<1)) #define rson(x) ((x<<1)|1) #define inf 0x3f3f3f3f typedef long long ll; typedef unsigned long long ull; using namespace std; const int maxn = 3e5+5; priority_queue<pii,vector<pii>,greater<pii>>a; int has[maxn]; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int i, j, k, m, n; cin>>n; ll ans =0; for(int i= 1;i<=n;++i) { cin>>k; a.push(mp(k,i)); if(a.top().first>=k)continue; ans+=k-a.top().first; if(!has[a.top().second]) { a.pop(); has[i]=1; } else{ has[a.top().second]=0; has[i]=1; } } cout<<ans<<endl; return 0; }