博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF865D Buy Low Sell High
阅读量:5893 次
发布时间:2019-06-19

本文共 1233 字,大约阅读时间需要 4 分钟。

题意翻译

已知接下来N天的股票价格,每天你可以买进一股股票,卖出一股股票,或者什么也不做.N天之后你拥有的股票应为0,当然,希望这N天内能够赚足够多的钱.

输入:
第一行一个整数天数N(2<=N<=300000).
第二行N个数字p1,p2...pN(1<=pi<=10^6),表示每天的价格.
输出: N天结束后能获得的最大利润.

题解

非常经典的贪心问题

 

用一个优先队列小根堆。

假设每个股票都买入。

当前的股票价格>堆顶的时候,把这个股票加进去两次。然后弹出堆顶。

否则加进去一次。

把这个差价计入ans,ans+=price[i]-q.top()

 

什么意义呢?

首先,我们虽然假设都买入,但是并不一定都买。

我们只有在计算差价的时候,相当于才会把某个价格买入,再以price[i]卖出。

而我们把这个股票加进去两次,

一次是正常的假设买入。为了之后可能赚取差价。

另一次是为了反悔。

假设股票价格是:3 7 10

最优解是3买入,10卖出,赚7元

也就是说,我以3价格买入,但我会在7元的时候卖出。

但是7元卖可能不是最优秀的。

所以,我们把7元再加进去,当轮到10元的时候,这个7元会再当做一个股票卖出ans+=10-7

发现,有意思的是,10-3=(10-7)+(7-3)

这就相当于3元买入,10元卖出。7元这天摸鱼。

如果10后面假设还有一个20

即3,7,10,20

那么,我们10元之后,队列里有7,10,10

20元会7元买入,20元卖出。相当于7元这天买入了一股。

 

这样下去,我们总能把最少的价格买入,尽量多的价格卖出。

如果不是最优秀的话,就不买不卖了。就是最后优先队列里剩下的一些。就是预定买入,但是实际没有买入的部分。

 

#include
using namespace std;const int N=300000+10;int n;int p[N];priority_queue
,greater
>q;long long ans;int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&p[i]); q.push(p[i]); if(!q.empty()&&q.top()

总结:

反悔堆的比较厉害的应用了。

利用差价的关系,直接处理。

怎么想到的?

首先要想到贪心,然后这个题肯定要用一个反悔堆之类。

那么,我们假设先买入,还是先都不买?

都不买太被动。

那就都买入,然后结算的时候,再真实买入。

但是对于不是最优的抛售天怎么办?

利用差价。即可。

转载于:https://www.cnblogs.com/Miracevin/p/9686577.html

你可能感兴趣的文章
MVC调用SVC无法找到资源解决问题
查看>>
div加jquery实现iframe标签的功能
查看>>
解决Yapi 插件运行不支持文件上传的问题解决
查看>>
Windows路由表详解
查看>>
MySQL从库记录binlog日志出错一例
查看>>
2015年度扯淡
查看>>
phpcms2008列表页模板与内容页模板list.html show.html
查看>>
Java程序员从笨鸟到菜鸟之(八十四)深入浅出Ajax
查看>>
GNS3全面详解系列-GNS3的前世今生
查看>>
JDK 1.8.0_144 集合框架之CopyOnWriteArrayList
查看>>
linux 将大文件分成小文件
查看>>
CCNA- 距离矢量路由协议学习
查看>>
jira 配置 LDAP 访问
查看>>
Canonical发布Ubuntu server 11.10版本
查看>>
企业实践用户邮箱导入/导出(第2部分)
查看>>
我的友情链接
查看>>
nagios搭建(五):nagios监控mysql
查看>>
AIX ftp 530 User root access denied
查看>>
【Java记录】try-with-resources的一个坑
查看>>
如何学习Linux命令-初级篇
查看>>