• Jzoj4835 量化交易


    一眼就可以看出是贪心,问题就是怎么去操作

    首先一个很显然的思路就是,开一个小根堆,每次对于一个价格x,如果低于堆顶我们就将其丢进去,否则将堆顶y取出,获得x-y的贡献

    但是这样是有问题的,我们会发现有反例: 1 4 2 3 用这种方法求出的答案是1但是正确答案应该是2

    所以我们需要增加一种“撤销操作”

    类似于种花那道题,我们每次将答案加上了x-y时候,我们也将x丢入堆中,而且要丢入两次,为什么?

    举个例子:1 2 3 4

    我们在做到2的时候,我们将第一天的股票卖了得到1的收益,但是实际上,2这一天不应该卖反而应该买,所以原本在第2天的交易量由-1变为了1,变化量为2

    也就是说,对于一个对答案做出贡献的x,我们将其丢入堆中*2,则第一次取出,相当于撤回一次出售,比如对于第三天的3(收益为3-(2-1)=2)

    第二次取出,则相当于将其也作为买入的一天,比如第四天(4-2=2)

    所以总收入为2+2=4

    这题卡常,建议手打堆(我过了是因为jz跑得快)

    #include<stdio.h>
    #include<queue>
    using namespace std;
    int main(){
    	freopen("trade.in","r",stdin);
    	freopen("trade.out","w",stdout);
    	for(int n,T=1;~scanf("%d",&n);++T){
    		unsigned ans=0;
    		priority_queue<int,vector<int>,greater<int> > q;
    		for(int x,i=0;i<n;++i){
    			scanf("%d",&x);
    			if(q.empty()||x<=q.top()) q.push(x);
    			else {
    				ans+=x-q.top(); q.pop();
    				q.push(x); q.push(x);
    			}
    		}
    		printf("Case #%d: %u
    ",T,ans);
    	}
    }

  • 相关阅读:
    存储过程编译出现锁死情况的解决方法
    国庆带你回家
    端午假期·广州之旅
    造成开发效率底下并且代码难以维护的 35 个恶习
    Linux下mysql自动备份脚本
    在咸阳机场等候登机有感
    vant3图片二进制上传
    浅谈前端缓存(转至大佬)
    vue3中使用$nextTick
    调取接口分页
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477268.html
Copyright © 2020-2023  润新知