一本通上的某動態規劃題:股票買賣(openjudge->NOI->2.6->8464)

題目:

8464:股票買賣

總時間限制:

1000ms

內存限制:

65536kB

描述

最近越來越多的人都投身股市,阿福也有點心動了。謹記着“股市有風險,入市需謹慎”,阿福決定先來研究一下簡化版的股票買賣問題。

假設阿福已經準確預測出了某隻股票在未來 N 天的價格,他希望買賣兩次,使得獲得的利潤最高。爲了計算簡單起見,利潤的計算方式爲賣出的價格減去買入的價格。

同一天可以進行多次買賣。但是在第一次買入之後,必須要先賣出,然後纔可以第二次買入。

現在,阿福想知道他最多可以獲得多少利潤。

輸入
輸入的第一行是一個整數 T (T <= 50) ,表示一共有 T 組數據。
接下來的每組數據,第一行是一個整數 N (1 <= N <= 100, 000) ,表示一共有 N 天。第二行是 N 個被空格分開的整數,表示每天該股票的價格。該股票每天的價格的絕對值均不會超過 1,000,000 。
輸出
對於每組數據,輸出一行。該行包含一個整數,表示阿福能夠獲得的最大的利潤。
樣例輸入

3
7
5 14 -2 4 9 3 17
6
6 8 7 4 1 -2
4
18 9 5 2
樣例輸出

28
2
0
提示
對於第一組樣例,阿福可以第 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

據說是經典的算法,看了書上給的代碼還是很懵逼,自己跟着程序寫一寫過程,看一看各數組的值就大概懂了一點。思路爲:先記錄下進行一次交易時各天的到目前爲止最大利潤,再倒着進行一次,得到各天到結束日的最大利潤,相加後遍歷求最大的那天利潤。詳情參見代碼,註釋是自己瞎理解的,慎讀。PS : POJ的2479可以用這種思路去做,稍加改動即可。


#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;
}

發佈了28 篇原創文章 · 獲贊 1 · 訪問量 6764
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章