zoukankan      html  css  js  c++  java
  • 【CF865D】Buy Low Sell High(贪心)

    【CF865D】Buy Low Sell High(贪心)

    题面

    洛谷
    CF

    题解

    首先有一个(O(n^2))(dp)很显然,设(f[i][j])表示前(i)天手中还有(j)股股票的最大收益。转移显然。
    然而这样子似乎并没有什么优化的余地。
    考虑这样子一个贪心,假设我们已经知道了前面(n-1)天在最优答案的情况下的购买和卖出情况,只考虑最后这一天,那么你会找到一个可以买入股票的一天,并且其价格最小,然后和这一天的股票价格进行比较,如果更低,你就会在那一天买入股票,在这一天卖掉。
    但是如果从头到尾每天都这样子进行贪心,那么显然是假的。
    那么我们这么处理,维护一个堆表示之前的所有可行的决策,如果当前天的价格还要小于堆中的最小值,显然我们不会购买,直接把这个价格丢进堆里,否则会在堆顶那天买入,在这一天卖出,假设堆顶那一天的价格是(x),当天的价格是(y),那么就会得到(y-x)的收益。但是后面某天的决策可能是在那一天卖出,在第(x)天买入,所以往堆里面再插入一个(x-(y-x)),那么如果你在后面的某天购买到了这个(x-(y-x)),即表示你把当前这一天的卖出操作替换成了在后面那一天卖出,然后再在堆内插入一个(y),因为前面插入的元素一定会在这个(y)之前被弹出堆,因此只可能在这一天不卖之后才会用到这个(y),表示在这一天买入。
    那么这样子贪心就好了。

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    #define ll long long
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    ll ans;int n;
    priority_queue<int> Q;
    int main()
    {
    	n=read();Q.push(-read());
    	for(int i=2;i<=n;++i)
    	{
    		int y=read();
    		if(y<=-Q.top())Q.push(-y);
    		else ans+=y+Q.top(),Q.pop(),Q.push(-y),Q.push(-y);
    	}
    	printf("%I64d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    jni中调用java方法获取当前apk的签名文件md5值
    Android底层驱动开发(一)
    作为原作者你能忍吗?
    SUN dataset图像数据集下载
    计算机视觉和图像处理常用的一些标准图片
    Docker基础技术:DeviceMapper
    Docker基础技术:AUFS
    Docker基础技术:Linux CGroup
    Docker基础技术:Linux Namespace(下)
    Docker基础技术:Linux Namespace(上)
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10574073.html
Copyright © 2011-2022 走看看