zoukankan      html  css  js  c++  java
  • CF865D Buy Low Sell High——反悔贪心堆

    做题链接

    题面

    已知接下来(N)天的股票价格,每天你可以买进一股股票,卖出一股股票,或者什么也不做.(N)天之后你拥有的股

    票应为(0),当然,希望这N天内能够赚足够多的钱.

    输入:

    第一行一个整数天数(N)((2<=N<=300000)).

    第二行N个数字(p_1,p_2...p_N)((1<=pi<=10^6)),表示每天的价格.

    输出: (N)天结束后能获得的最大利润.

    思路

    我们可以快速想出一种贪心策略:买入价格最小的股票,在可以赚钱的当天卖出。

    显然我们可以发现,上面的贪心策略是错误的,因为我们买入的股票可以等到可以赚最多的当天在卖

    出。我们考虑设计一种反悔策略,使所有的贪心情况都可以得到全局最优解。(即设计反悔自动机的反

    悔策略)定义(C_{buy})为全局最优解中买入当天的价格, (C_{sell}) 为全局最优解中卖出当天的价格,则:

    (C_{sell}-C_{buy}=(C_{sell}-C_{i})+(C_{i}-C_{buy}))

    (C_i)为任意一天的股票价格

    考虑怎么反悔

    我们将每天的价格视为一个个"选项", 压入小根堆中,为了保证买入操作在卖出操作之前,我们从前往

    后扫描(p),对于现在的价格 (p_i),如果堆顶元素(p_j) 满足 (p_{j}<p_i) ,那么,我们取出

    堆顶,在第(j)天买入股票,在第(i)天卖出股票,此时,我们就可以获得(p_i - p_j) 的收益

    然而,如果之后有(p_k)满足(p_k > p_i),辣么,我们当前作出的决策可能并不是最优的,

    如何反悔呢?

    于是,当我们进行上述操作时,我们将(p_i)也压入堆中,增加一个(p_i)的选项,弹出时,我们相当

    于将(p_j)按照(p_i)的价格又买了回来

    就比如我们 (4 5 6)这个序列,按照程序我们应该是先买入(4),然后卖出(5)(ans+=1),但是显然后面

    在6的时候卖会更优,所以我们为了给电脑留出余地,我们再多保存一个历史的状态,再往队列中压入一

    个5,这个时候我们还会在6的时候,卖出,并且(ans+=1),正确

    其实就相当于是(ans=(6-5)+(5-4)=6-4)

    代码

    自己写

  • 相关阅读:
    WP开发笔记——页面传参
    WP开发笔记——控件倾斜效果
    WP开发笔记——不同Item显示不同ApplicationBar:适用于Pivot与Panorama
    WP开发笔记——WP APP添加页面跳转动画
    WP开发笔记——去除 HTML 标签
    WP开发笔记——字符串 转 MD5 加密
    WP开发笔记——WP7 SDK使用技巧
    sphinx,coreseek安装
    yii2从零开始一,安装
    array_filter函数
  • 原文地址:https://www.cnblogs.com/bangdexuanyuan/p/13953544.html
Copyright © 2011-2022 走看看