假设我们准确预测梅西的价格为N
天。预测以列表形式给出,其中p_i
表示玩家在日i
的价格。鲍勃计划在此期间进行多次连续交易,但一次不能有多个梅西,因此在再次购买之前需要卖掉他。
B
开始,不能买一个费用超出他能力的梅西。当然,鲍勃可以通过购买和出售他的Messis获得任何利润。对他来说幸运的是,有些时候他开始与梅西一起打开一个随意的礼品包。
最后鲍勃只想获得尽可能多的利润,然后卖掉最后一次梅西。
输入格式:
在输入文件的第一行,您将找到3个整数,N,B和M.
N表示Bob预测梅西价格的天数。 B代表Bob的初始预算。 M可以是0或1;如果Bob在没有初始Messi的情况下开始卖出,则为0;如果他确实以最初的Messi开始卖出,则为1。
在下一行,你会发现N个整数:p1,p2,...,pN,用空格分隔,其中pi代表梅西在第i天的价格。
给出测试用例
测试1
7 5 0
20 10 30 5 10 10 20
正确答案:15
说明:Bob的初始预算为5,没有初始的Messi可供出售。他的价格下降到5之前他不能买任何梅西,所以他的利润只有(20-5)= 15
测试2
7 0 1
20 10 50 80 60 20 10
正确答案:90
说明: 鲍勃的初始预算为0,一个梅西出售。因此他卖掉了他最初的梅西20分,买回他10分,卖给他80分,所以他的利润是20 +(80-10)= 90
这个问题是在一次采访中给我的,但是我无法提供一个有效的解决方案。与此同时,我发现了一些关于这个问题的更简单的变体,例如Maximum profit by buying and selling a share at most twice,但我一直没有成功地理解如何使思维适应我的问题。
到目前为止,我只能提出一种超出我给出的时间限制的强力解决方案(C ++为0.1秒,其中1 <= N <= 10 ^ 5)。
我正在寻找一种解决方案和一种思考这类问题的方法,我似乎无法找到正确的思考方式。
答案 0 :(得分:2)
我们可以使用动态编程。
如果我们在一天开始时没有Messi f0(i)
,我们可以将i
定义为我们可以获得的最高预算。
如果我们得到他,请f1(i)
为相同的值。
i = 0
的基本值取决于我们是否在一开始就拥有他。
转换如下:
我们可以从i
转到i + 1
并且什么都不做
如果我们有梅西,我们可以卖他(设置f0(i + 1) = max(f0(i + 1), f1(i) + price(i))
)
如果我们没有他,我们的预算足够大,我们可以买他
(做f1(i + 1) = max(f1(i + 1), f0(i) - price(i))
)
答案是f0(n)
(这意味着所有日子过去了,我们没有他)。
这个解决方案显然需要线性的时间和空间,所以任何 合理的C ++实现应该符合您的要求。
答案 1 :(得分:1)
问题的第一个简化是转换最初的礼物&#34;在梅西的初始价格下,梅西获得相同数额的金钱。用户可以选择在开始时回购梅西。
之后,您会发现第一个价格足以让用户购买梅西,并在此之前丢弃每个预测。然后,查找预测价格的所有本地最小和本地最大值,并购买所有最小值并卖出所有最大值,但请记住不要回购,如果局部极小是最后的预测。
这应解决O(N)中的问题。
编辑:可以通过序列的二度差异找到局部最小值或最大值:
d[i] = p[i+1] - p[i]
d2[i] = d[i] - d[i-1]
如果d2[i] > 0
,则它是本地最小的;如果d2[i] < 0
,那么它是本地最大值。显然,你需要注意一些边界条件,但它不应该太难。
答案 2 :(得分:0)
// 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;