GYOJ_1812_股票(stock)

题目描述

2130年,股神巴菲特投胎了!他投胎到你身上!
你作为股神转世,能力比原股神还要强,你可以预测到今后n天的股价。假设刚开始你的手上有1元钱,你想知道n天后你最多可以赚到多少钱。作为股神转世,你准备自己编程算答案。
每一天你都可以买股票、卖股票,当然也可以什么都不干。(到那时股票可以买卖分数股)

输入输出格式

输入格式

第一行一个数n(n≤1000000)。接下来n行,每行一个小数,代表每天的股价。

输出格式

一个数,代表最多能赚多少钱。(答案四舍五入,保留整数)

样例

INPUT

2
2.00
3.00

OUTPUT

2

HINT

样例解释 Sample Explanation:
第一天有现金1元,股价2.00元,可以买入0.5股;第二天股价3.00元,全部卖出,得现金:0.5*3.00=1.50元,四舍五入后金额为2。

SOLUTION

贪心

一开始我还想一堆乱七八糟的解法,单调性,最长子序列,什么价格一下跌就卖啥的,但是都觉得很奇怪,都可以轻松被自己hack掉,于是瞄了一眼AC的人的评测状态,woc,代码都这么短的吗???但还是没有思路。

最后还是戳了题解看。非常简单的做法。

我们保存两个值,一个是当前可以赚的钱数的最大值,另一个是当前可以持有股份的最大值。因为我们的操作非常单一,只有买进,卖出两种。所以我们要用手上的钱去在合适的时候买进卖出利滚利滚利滚利

本题利用到了“可以买入,卖出,或者什么也不干”这个性质,于是用最优值更新相当于就是从上一次更新到下一个最优值的出现期间不做任何操作,从而保证可以用最优创造一个新的最优。

#include <iostream>
#include <cstdio>
using namespace std;
#define Min(a,b) ((a<b)?a:b)
#define Max(a,b) ((a>b)?a:b)
double hv=0,ans=1;
int main(){
	int i,n;
	scanf("%d",&n);
	for (i=1;i<=n;++i){double x;
		scanf("%lf",&x);
		double rec=Max(ans,hv*x);//记录如果现在全部卖出的话的钱数
		hv=Max(hv,ans/x);ans=rec;//记录如果用历史最大钱数来买的话能卖多少 
	}
	printf("%0.0lf",ans);
	return 0; 
}
原文地址:https://www.cnblogs.com/hkpls/p/9829870.html