量化交易——解题报告

题目链接:

http://172.25.37.251/problem/22

题目大意:

i i i天可以以 v [ i ] v[i] v[i]的价格买进或卖出一只股票,或者什么也不干,求出能够获得的最大利益。

题目分析:

1.观察数据范围我们可以发现,这是一个 O ( n l o g n ) O(nlogn) O(nlogn)的题,由于题目问题,排除二分的可能,那就只剩下数据结构了。
2.我们可以发现如果我以 a a a买进一只股票,然后以 b b b卖出,或者以 a a a买进一只股票,然后以 c c c卖出 ( b < c ) (b<c) (b<c),那么显然对于 a a a来说在 c c c的时候卖合适。但是由于复杂的相关性问题,导致我们不能无脑找到差值最大的两天来操作。
3.我们发现假如以 a a a买进一只股票,然后以 c c c卖出,和以 a a a买进一只股票,然后以 b b b卖出,以 b b b买进一只股票然后以 c c c卖出是一样的,所以我们开始可以尽量卖,反正在后面是可以通过替换来使答案更大的,如何保证每次替换都是最优的操作呢?那就是每次处理掉前面最小的就行(维护一个堆啊)。

正解程序:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>

using namespace std;
typedef long long ll;
const ll maxn=100010;
ll n,Pri[maxn];
int main()
{
	ll T=0;
	while(scanf("%lld",&n)!=EOF)
	{
		multiset<ll> s;
		T++;
		ll ans=0;
		for(ll i=1;i<=n;i++)
		{
			scanf("%lld",&Pri[i]);
			if(!s.empty())
			{
				multiset<ll>::iterator top=s.begin();
				if(Pri[i]>(*top))
				{
					s.erase(top);
					ans=ans+Pri[i]-(*top);
					s.insert(Pri[i]);
					s.insert(Pri[i]);
				}
				else
					s.insert(Pri[i]);
			}
			else if(i==1)
				s.insert(Pri[i]);
		}
		printf("Case #%lld: %lld\n",T,ans);
	}
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值