**FJNU2018第三次欢乐良心(被狗吃了)友谊赛B题题解**

首先先感谢董哥和嘉琦学姐的良心(毒瘤)题,以及即将去考研的fuls让我有能写第一条博客的机会。
切入正题,我们先看题目:

You can perfectly predict the price of a certain stock for the next
N days. You would like to profit on this knowledge, but only want to
transact one share of stock per day. That is, each day you will either
buy one share, sell one share, or do nothing. Initially you own zero
shares, and you cannot sell shares when you don’t own any. At the end
of the N days you would like to again own zero shares, but want to
have as much money as possible.

input

Input begins with an integer N (2 ≤ N ≤ 3·105), the number of days.
Following this is a line with exactly N integers p1, p2, …, pN
(1 ≤ pi ≤ 106). The price of one share of stock on the i-th day is
given by pi.

output

Print the maximum amount of money you can end up with at the end of
N days.

examples

Input

9
10 5 4 7 9 12 6 2 10

Output

20

Input

20
3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4

Output

41

题意:这就是个股票买卖问题。就是假设你很牛逼,可以预知未来n天的股票走势,但是你只能一天买一支或者卖一支股票,并且最后你手里要没有股票,假设你有无限多的钱,请问你能够得到的利润的多少。
思路:
刚开始拿到这道题,我被良心这两个字骗了,以为这就是道暴力题。于是开始就直接上手两个for,寻找a[j]-a[i]的最大值,累加到ans,然后把a[j]和a[i]存入浮点数(下次就不会访问这两个数了),然后就是很自然的,tle了。
在这里插入图片描述
本着一颗做不出来就给毒瘤出题人寄刀片的心,为了节省我的刀片,我翻开了c++从入门到精通(放弃),经过了60多页的搜索,我终于在第314页找到的想要的容器适配器priority_queue,作用是排列自身对象,将最大值放在队伍最前列。
为什么选用这个容器,而不用queue,因为这个题目的难点在于股票是必须先买后卖的,并且手中可以拥有多支股票,直接使用queue连第二个样例都过不了
在这里插入图片描述
于是我就有了思路2:
我们把a放入优先队列里,然后遇到有收益的b时(不一定是最优解),将收益(b-a)先放入ans中,然后将a弹出来(pop()),将b放入优先队列两次,让后再遇到c时将b拿出来,那收益就是(c-b)放入ans,此时ans=(b-a)+(c-b)=(c-a),这里的b就充当了一个跳板,以此类推就能找到最优解。
在这里插入图片描述
AC代码:

#include <queue>
#include <cstring>
#include <cstdio>
#include<cmath>
using namespace std;
priority_queue<int>st; //我寻你千百度
int main(){
 int n;
 long long a;
 long long ans=0;
 scanf("%d",&n);
    for(int i=0;i<n;i++) {
        scanf("%lld",&a);
        if(!st.empty()&&abs(st.top())<a)
        {
         ans=ans+(a-abs(st.top()));
         st.pop();
         st.push(-a);
         st.push(-a);  
  }
  else {
   st.push(-a);
  }
 }
 printf("%lld",ans);   //学业不精告辞
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值