YBT 股票买卖
題目描述
最近越來越多的人都投身股市,阿福也有點心動了。謹記著“股市有風險,入市需謹慎”,阿福決定先來研究一下簡化版的股票買賣問題。
假設阿福已經準確預測出了某只股票在未來N天的價格,他希望買賣兩次,使得獲得的利潤最高。為了計算簡單起見,利潤的計算方式為賣出的價格減去買入的價格。
同一天可以進行多次買賣。但是在第一次買入之后,必須要先賣出,然后才可以第二次買入。
現在,阿福想知道他最多可以獲得多少利潤。
輸入格式
輸入的第一行是一個整數T(T≤50),表示一共有T組數據。
接下來的每組數據,第一行是一個整數N(1≤N≤100,000),表示一共有N天。第二行是 N 個被空格分開的整數,表示每天該股票的價格。該股票每天的價格的絕對值均不會超過1,000,000。
輸出格式
對于每組數據,輸出一行。該行包含一個整數,表示阿福能夠獲得的最大的利潤。
輸入樣例
3
7
5 14 -2 4 9 3 1
7
6 6 8 7 4 1 -2
4
18 9 5 2
輸出樣例
28
2
0
題解
我們可以用$dp1[i]$表示第$1$天到第$i$天買賣第一次股票的最大值,$dp2[i]$表示第$i$天到第$n$天買賣第二次股票的最大值。
易得$ans =underset{1 leqslant i leqslant n}{max} left { dp1[i] + dp2[i] ight }$。
#include <iostream>
#include <cstdio>
#define MAX_N (100000 + 5)
using namespace std;
int T;
int n;
int a[MAX_N];
int dp1[MAX_N], dp2[MAX_N];
int ans;
int main()
{
scanf("%d", &T);
int mina, maxa;
while(T--)
{
scanf("%d", &n);
for(register int i = 1; i <= n; ++i)
{
scanf("%d", a + i);
}
dp1[0] = dp2[n + 1] = ans = -0x7f7f7f7f;
mina = 0x7f7f7f7f;
maxa = -0x7f7f7f7f;
for(register int i = 1; i <= n; ++i)
{
mina = min(mina, a[i]);
dp1[i] = max(dp1[i - 1], a[i] - mina);
}
for(register int i = n; i; --i)
{
maxa = max(maxa, a[i]);
dp2[i] = max(dp2[i + 1], maxa - a[i]);
}
for(register int i = 1; i <= n; ++i)
{
ans = max(ans, dp1[i] + dp2[i]);
}
cout << ans << "
";
}
return 0;
}
參考程序
總結
- 上一篇: linux使用openssl查看文件的m
- 下一篇: 第十节 lxml.etree解析HTML