zoukankan      html  css  js  c++  java
  • 2019年9月20日晚间测试-T2

    【问题描述】
    applepi训练了一个可以自动在股票市场进行量化交易的模型。通常来说,训练了一个可以自动在股票市场进行量化交易的模型。你懂得就好比一架印钞机。不过为了谨慎起见applepi还是想先检查一下模型的效果。
    applpie收集了“塞帕思股份收集了“塞帕思股份(surpass)”在最近的连续”在最近的连续N天内的价格。在每一天内的价格。在每一天中,他可以做如下事情之一:
    1. 睡(把)觉妹。睡(把)觉妹。
    2. 以当天的价格作为成交买入1股“塞帕思”的票。
    3. 以当天的价格作为成交卖出1股“塞帕思”的票。
    最初applepi不持有该股票。现在你需要计算出最优策略下,不持有该股票。现在你需要计算出最优策略下,N天后applepi能够获得的最大利润。

    为了维护森林和平,本着清仓甩锅原则在N天的交易结束后applepi也不能持有“塞帕思”的股票。
    【输入格式】
    每个测试点包含若干组数据,以EOF结尾。对于每组数据:
    第一行1个整数N。
    第二行N个正整数,相邻两之间用1个空格隔开,表示每一天股票的价格。


    这道题给人一种——哇看上去不是很难——的感觉,但实际上,呵呵。

    我一看,就觉得这个是数据结构优化的动态规划——然后就打了个暴力,GG(T_T)

    事后到网上搜了搜,才发现这是一个:用反悔堆维护的贪心。嘤嘤嘤(つД`)

    具体是怎么做的呢?  [・_・?]

    首先,我们贪心的想,怎么获得最大了利润呢?

    因为最后手里不能剩下股票,所以每一次买都得对应一次卖

    在最便宜的那天买进,在最昂贵的那天卖出,这就是最大利润。

    什么时候算最便宜?什么时候算最贵?  ?(。ヘ°)

    虽然看上去问题丝毫没有进展,但至少我们知道了一个方向。  ︿( ̄︶ ̄)︿

    我们没办法找到全局的,那就先只关注眼前的利益——

    如果今天的 股票价格 比我们买进的股票当中 花费最小 的那一张 要小 ,那我们就把 手里的那张股票卖出去。

    反之,如果今天的股票价格比我们手中最小的还要小,或者手里根本就没有股票,那这时候肯定不能卖,买进它肯定更优。

    当然这可能还是没有任何用处,因为你还是不知道在全局上到底什么时候买卖。(显然。想一想,为什么)

    例如:对于数据 a = 10、b = 11、c = 20,这种贪心会在10时买进,11时卖出,但事实上在20时卖出会更优。

    吃后悔药从新买卖不就成了,至此,终于该请出我们的反悔堆了!(~ ̄▽ ̄)~ 

    反悔堆最重要的就是怎么反悔(废话)

    那就想一想,咱们都有可能做什么样错误决定,

    ① 这天卖出去不是最优的,但却卖了

    ② 这天应该买进,但却没有买

    对于第一种情况,就仍然用上面的那个例子吧。

    当我们遇见 b 的时候,自以为很优,就把 a 卖了,这时的利润:( b - a )

    但当我们遇见 c 的时候才发现其实( c - a )是最优的。

    可我们怎么把( b - a )变成( c - a )呢?

    把差价补齐就行了—— ( b - a ) + ( c - b ) = c - a

    我们在 b 卖出时,把 b 也放进堆里,当发现有差价时( c > b ),就把差价补上 ans += ( c - b )

    只需要把 b 放进堆里,一开始的贪心思路就会自动帮我们处理这个了

    对于第二种情况就更简单了,不是没买吗?假装我们买了,把 b 放进堆里。╮( ̄▽ ̄)╭

    这样,用一个简单的贪心思路,加上每在 b 卖出,就放 两个 b进去的反悔方式,我们就A掉这道题了。φ(>ω<*) 

    下附代码:( ̄▽ ̄)~*

    #include<bits/stdc++.h>
    using namespace std;
    
    long long ans;// 答案
    priority_queue< long long , vector< long long > , greater< long long > > q;
    // 贪心用的堆,每次拿出来最小的比较
    
    int main()
    {
        int cnt = 0;// 第几组
        int n; 
        
        // 因为不知道几组,就这么输入
        while ( scanf("%d", &n) != EOF )
        {
            cnt++;// 第几组 
            
            // 清空上一组留下的数据
            ans = 0; 
            while ( !q.empty() ) q.pop();
            
            for ( int i = 1; i <= n; i++ )
            {
                int now;
                // 因为我们只在乎堆中的和当前的
                // 所以就不用数组存了 
                scanf("%d", &now);
                
                if ( q.empty() || q.top() >= now )
                {
                    // 发现不能卖,就先假装买了 
                    q.push( now );
                }
                else
                {
                    
                    ans += now - q.top();// 可以卖就卖了 
                    q.pop();
                    
                    q.push( now );
                    // 为补差价做准备
                    
                    q.push( now );
                    // 防止该买没买
                }
            }
                
            printf("Case #%d: %lld
    ",cnt,ans);
            
        }
        
        return 0;
    }

    感谢机房巨佬:在想peach 的帮助 Thanks♪(・ω・)ノ

    (✪ω✪)CSP(NOIP)RP++

  • 相关阅读:
    powershell命令大全
    Android USB Connections Explained: MTP, PTP, and USB Mass Storage
    安装Windows Metasploit Framework
    Sublime Text2 jedi插件离线安装
    MySQL下载安装配置和Navicat for MySQL的安装配置
    Sublime中文编码问题
    Flask入门之结构重组(瘦身)-第13讲笔记
    Flask入门之SQLAlchemy配置与数据库连接
    Flask入门之flask-wtf表单处理
    Total Command使用笔记
  • 原文地址:https://www.cnblogs.com/Cainai-Liberty-Bird/p/11561677.html
Copyright © 2011-2022 走看看