8464:股票買賣
- 總時間限制:
1000ms
內存限制:
65536kB
- 描述
最近越來越多的人都投身股市,阿福也有點心動了。謹記着“股市有風險,入市需謹慎”,阿福決定先來研究一下簡化版的股票買賣問題。
假設阿福已經準確預測出了某隻股票在未來 N 天的價格,他希望買賣兩次,使得獲得的利潤最高。爲了計算簡單起見,利潤的計算方式爲賣出的價格減去買入的價格。
同一天可以進行多次買賣。但是在第一次買入之後,必須要先賣出,然後纔可以第二次買入。
現在,阿福想知道他最多可以獲得多少利潤。
- 輸入
- 輸入的第一行是一個整數 T (T <= 50) ,表示一共有 T 組數據。
接下來的每組數據,第一行是一個整數 N (1 <= N <= 100, 000) ,表示一共有 N 天。第二行是 N 個被空格分開的整數,表示每天該股票的價格。該股票每天的價格的絕對值均不會超過 1,000,000 。 - 輸出
- 對於每組數據,輸出一行。該行包含一個整數,表示阿福能夠獲得的最大的利潤。
- 樣例輸入
- 375 14 -2 4 9 3 1766 8 7 4 1 -2418 9 5 2
- 樣例輸出
- 2820
- 提示
- 對於第一組樣例,阿福可以第 1 次在第 1 天買入(價格爲 5 ),然後在第 2 天賣出(價格爲 14 )。第 2 次在第 3 天買入(價格爲 -2 ),然後在第 7 天賣出(價格爲 17 )。一共獲得的利潤是 (14 - 5) + (17 - (-2)) = 28
對於第二組樣例,阿福可以第 1 次在第 1 天買入(價格爲 6 ),然後在第 2 天賣出(價格爲 8 )。第 2 次仍然在第 2 天買入,然後在第 2 天賣出。一共獲得的利潤是 8 - 6 = 2
對於第三組樣例,由於價格一直在下跌,阿福可以隨便選擇一天買入之後迅速賣出。獲得的最大利潤爲 0
#include<iostream>
using namespace std;
int price[100001],minprice[100001],maxprice[100001],first[100001],second[100001];
int t,n,result;
int main()
{
scanf("%d",&t);//測試數據數
while(t--)
{
result=0;
scanf("%d",&n);//n天的股價
for(int i=1;i<=n;i++)
scanf("%d",&price[i]);
//如果交易一次
minprice[1]=price[1];//從第一天算起
first[1]=0;//如果只有一天,利潤爲0
for(int i=2;i<=n;i++)
{
minprice[i]=min(minprice[i-1],price[i]);//表示到i天爲止的最低價格
first[i]=max(first[i-1],price[i]-minprice[i]);//到i天爲止的最大利潤
}
//因爲有第二次交易,以下代表了從第i天到第n天的最大利潤
//準確來說爲了代碼簡潔計算也方便,我們求的是第n天到第i天的最大利潤
maxprice[n]=price[n];
second[n]=0;//初始化同上
for(int i=n-1;i>=1;i--)
{
maxprice[i]=max(maxprice[i+1],price[i]);
second[i]=max(second[i+1],maxprice[i]-price[i]);
}
//first代表了第一天到第i天的最大利潤,second代表了第i天到第n天的最大利潤
//因爲可以當天買當天賣,不需要first[i]+second[i+1];
for(int i=1;i<=n;i++)
result=max(result,first[i]+second[i]);
printf("%d\n",result);
}
return 0;
}