123. 买卖股票的最佳时机 III
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
思路:第一眼,就是要使用动态规划去做,我们可以设
d
p
1
表
示
第
1
次
买
入
的
最
低
价
格
d
p
1
=
m
i
n
(
d
p
1
,
p
r
i
c
e
s
[
i
]
)
dp1表示第1次买入的最低价格 dp1=min(dp1,prices[i])
dp1表示第1次买入的最低价格dp1=min(dp1,prices[i])
d
p
2
表
示
第
2
次
卖
出
后
的
最
大
利
润
d
p
2
=
m
a
x
(
d
p
2
,
p
r
i
c
e
s
[
i
]
−
d
p
1
)
dp2表示第2次卖出后的最大利润 dp2=max(dp2,prices[i]-dp1)
dp2表示第2次卖出后的最大利润dp2=max(dp2,prices[i]−dp1)
d
p
3
表
示
第
3
次
买
入
的
最
大
利
润
d
p
3
=
m
a
x
(
d
p
3
,
d
p
2
−
p
r
i
c
e
s
[
i
]
)
dp3表示第3次买入的最大利润 dp3=max(dp3,dp2-prices[i])
dp3表示第3次买入的最大利润dp3=max(dp3,dp2−prices[i])
d
p
4
表
示
第
4
次
卖
出
后
的
最
大
利
润
d
p
4
=
m
a
x
(
d
p
4
,
d
p
3
+
p
r
i
c
e
s
[
i
]
)
dp4表示第4次卖出后的最大利润 dp4=max(dp4,dp3+prices[i])
dp4表示第4次卖出后的最大利润dp4=max(dp4,dp3+prices[i])
则程序如下:
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size()<2)
return 0;
int dp1=INT_MAX;
int dp2=0;
int dp3=INT_MIN;//第3次买入的最大利润(已经赚的钱-当前股票价格)可能是个负利润
int dp4=0;
for(int i=0;i<prices.size();i++)
{
dp1=min(dp1,prices[i]);
dp2=max(dp2,prices[i]-dp1);
dp3=max(dp3,dp2-prices[i]);
dp4=max(dp4,dp3+prices[i]);
}
return dp4;
}
};
188. 买卖股票的最佳时机 IV
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。
注意: 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
思路:三维数组
d
p
[
k
]
[
i
]
[
2
]
dp[k][i][2]
dp[k][i][2]
i 表示到了第几天,k表示进行了几次交易,2表示两种状态 0手上无股票 1手上有股票
d
p
[
k
]
[
i
]
[
0
]
dp[k][i][0]
dp[k][i][0]数组中的数字表示到了第i天,交易了k次,手上没有股票的最大利益
d
p
[
k
]
[
i
]
[
1
]
dp[k][i][1]
dp[k][i][1] 数组中的数字表示到了第i天,交易了k次,手上有股票的最大利益
我们这里假设买入一次算一次交易
则有状态转移方程
dp[t][i][0]=max(dp[t][i-1][0],dp[t][i-1][1]+prices[i-1])
第i天为止第t次交易手上不持有=第i-1天为止第t次交易手上不持有,第i-1天为止第t次交易手上持有然后卖出()+prices[i-1]
dp[t][i][1] = max(dp[t][i - 1][1], dp[t - 1][i - 1][0] - prices[i - 1]);
第i天为止第t次交易手上持有=第i-1天为止第t次交易手上持有,第i-1天为止第t-1次交易手上不持有然后卖如pricesi-1
当然,我们也需要注意,当k >= prices.size()/2时,说明根本完成不了k次交易,最多就是prices.size()/2时,这个问题就转换为股票问题2了,直接使用我们之前的代码即可。
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
if(!prices.size()) return 0;
if(k >= prices.size()/2)
{ //问题变为股票问题2
int sum = 0;q
for(int i = 1; i < prices.size(); i++)
{
int val = prices[i] - prices[i - 1];
sum += (val > 0? val: 0);
}
return sum;
}
vector<vector<vector<int>>> dp (k+1,vector<vector<int>>(prices.size()+1,vector<int>(2,0)));
for(int t=0;t<=k;t++)
dp[t][0][1]=INT_MIN;
for(int i=0;i<prices.size();i++)
dp[0][i][1]=INT_MIN;
for(int t=1;t<=k;t++)
{
for(int i=1;i<=prices.size();i++)
{
dp[t][i][0]=max(dp[t][i-1][0],dp[t][i-1][1]+prices[i-1]);
dp[t][i][1] = max(dp[t][i - 1][1], dp[t - 1][i - 1][0] - prices[i - 1]);
}
}
return dp[k][prices.size()][0];
}
};