假设我们有一个准确的预测梅西的价格一段时间的N天。这个预测是作为一个列表给出的,在这个列表中,p_i表示球员在日i中的价格。Bob计划在此期间进行多个连续的事务,但一次不能拥有多个Messi,因此需要在再次购买他之前卖掉他。
鲍勃从一个有限的预算B开始,不能买一个比他负担得起的更贵的梅西。当然,鲍勃可以在他的预算中增加他从买卖他的梅西斯中获得的任何利润。对他来说幸运的是,有些时候,他从事先打开一个随机的礼品包开始使用梅西。
最后,鲍勃只想得到尽可能多的利润,并出售最后梅西。
输入格式:
在输入文件的第一行,您将找到3个整数,N、B和M。
N表示Bob预测梅西价格的天数。B代表鲍勃的初步预算。M既可以是0,也可以是1;如果Bob开始时没有初始的Messi,则为0;如果他确实以初始的Messi开始出售,则为1。
在下一行中,您将找到N个整数: p1、p2、…,pN由一个空格分隔,其中pi代表梅西在第一天的价格。
给出的测试案例
测试1
7 5 0
20 10 30 5 10 10 20
正确答案: 15
说明:鲍勃最初的预算是5英镑,而不是最初的梅西。他不能买任何梅西,直到他的价格降到5,所以他的利润只有(20-5) = 15。
测试2
7 0 1
20 10 50 80 60 20 10
正确答案: 90
说明:鲍勃的初始预算为0,而梅西的初始预算为1美元。因此,他以20英镑的价格卖掉了最初的梅西,以10美元买回了他,然后以80英镑的价格卖掉了他,所以他的利润是20 + (80-10) = 90。
这个问题是在一次面试中给我的,我一直未能找到一个有效的解决方案。同时,我在这个问题上发现了一些更简单的变体,比如买卖一股最多两倍的最大利润,但是我在理解如何使思想适应我的问题方面没有成功。
到目前为止,我只想出了一个强力的解决方案,远远超出了给我的时间限制( C++是0.1秒,其中1 <= N <= 10^5)。
我正在寻找一种解决方案和思考这类问题的方法,我似乎找不到正确的方法来思考这个问题。
发布于 2017-01-03 20:26:45
我们可以使用动态规划。
f0(i)定义为如果在一天开始时没有i,我们可以获得的最大预算。如果我们抓住了他,让f1(i)成为同样的价值。i = 0的基值取决于我们一开始是否有他。- We can go from `i` to `i + 1` and do nothing
- If we have Messi, we can sell him (setting `f0(i + 1) = max(f0(i + 1), f1(i) + price(i))`)
- If we don't have him and our budget is big enough, we can buy him (doing `f1(i + 1) = max(f1(i + 1), f0(i) - price(i))`)
f0(n) (这意味着所有的日子都过去了,我们没有他)。这个解决方案显然需要线性的时间和空间,所以任何合理的C++实现都应该适合您的需求。
发布于 2017-01-03 20:28:19
首先,简化问题是将梅西最初的“礼物”以梅西最初的价格折算成等额的钱。用户可以选择要么买回梅西,要么在一开始就不买。
之后,你会发现第一个价格足够低的用户购买一个梅西,并放弃之前的每一个预测。然后,求出所有预测价格的局部极小和局部最大值,然后在所有最小值上买入,在所有最大值上卖出,但记住,如果局部极小值是最后的预测值,则不要回购。
这将解决O(N)中的问题。
编辑:通过序列的2度差可以找到局部最小或最大值:
d[i] = p[i+1] - p[i]
d2[i] = d[i] - d[i-1]如果是d2[i] > 0,则是局部极小;如果是d2[i] < 0,则为局部极大。显然会有一些边界条件,你需要处理,但它不应该太难。
发布于 2017-01-03 22:41:48
// input
long predictionLength;
long budget;
bool startWithMessi;
long prediction[MAX_PREDICTION_LENGTH];
// output
long profit;
ifstream fin;
fin.open( DATA_FILE_NAME );
fin >> predictionLength >> budget >> startWithMessi;
for( long day = 0; day < predictionLength; day++ )
fin >> prediction[day];
fin.close();
long money = budget;
bool messi = startWithMessi;
long dayIndex = 0;
while( dayIndex < predictionLength )
{
if( messi )
{
if( dayIndex == predictionLength - 1
|| prediction[dayIndex] > prediction[dayIndex + 1] )
{
money += prediction[dayIndex];
messi = false;
}
}
else
if( dayIndex < predictionLength - 1
&& prediction[dayIndex] < prediction[dayIndex + 1]
&& money >= prediction[dayIndex] )
{
money -= prediction[dayIndex];
messi = true;
}
dayIndex++;
}
profit = money - budget;
cout << profit << endl;https://stackoverflow.com/questions/41451482
复制相似问题