当前位置:网站首页>Have you ever seen this kind of dynamic programming -- the stock problem of state machine dynamic programming (Part 2)
Have you ever seen this kind of dynamic programming -- the stock problem of state machine dynamic programming (Part 2)
2022-07-28 21:43:00 【Worthless research monk】
Preface
In the first two articles Have you ever seen this kind of Dynamic Planning —— Stock problem of state machine dynamic programming ( On ) and Have you ever seen this kind of Dynamic Planning —— Stock problem of state machine dynamic programming ( in ) Already talked 4 Tao and stock related issues , Explained in detail State machine dynamic programming And his basic principles and application methods . In this article , I will introduce the remaining two stock issues , Continue to deepen and learn State machine dynamic programming .
The best time to buy and sell stocks includes the freezing period
subject
Given an array of integers prices, Among them the first prices[i] It means the first one i Day's share price .
Design an algorithm to calculate the maximum profit . Under the following constraints , You can do as many deals as you can ( Buy and sell a stock many times ): After sale of shares , You can't buy shares the next day ( That is, the freezing period is 1 God ).
Be careful : You can't participate in multiple transactions at the same time ( You have to sell the stock before you buy it again ).
Example
Example 1:
Input : prices = [1,2,3,0,2]
Output : 3
explain : The corresponding transaction status is : [ purchase , sell , Freezing period , purchase , sell ]
Example 2:
Input : prices = [1]
Output : 0
State representation array and state transition equation
Like the previous topic, first of all, we need to define the state and analyze the state transition , In this problem, we use a two-dimensional array dp[i][j] It represents the benefits under various states , In this problem, we have the following states :
dp[i][0], Indicates that you are traversing to theiThere is no buying or selling of stocks .- At this time, there is no buying or selling , At this time, the income and traversal reach the
i-1The situation of not buying and selling stocks is the same , Their income is equal to 0, namelydp[i][0] = 0,dp[i - 1][0] = 0.
- At this time, there is no buying or selling , At this time, the income and traversal reach the
dp[i][1], Indicates that you are traversing to theiWhen you buy stocks, you have stocks in your hands , This situation can be explained by 3、 ... and The situation shifts :- After traversing to the
i-1When you buy stocks, you already have stocks in your hands , At this time, you just need to keep in shape , Then in the first placeiThe return when buying stocks and thei-1The returns of each stock are equal , namelydp[i][1] = dp[i - 1][1]. - The second case is to traverse to the
i-1There is no stock in your hand when you buy a stock , At this time, if you want to have stocks in your hands, you need to buy , Then it will costprices[i], So when we traverse to theiWhen you buy a stock, the return is equal todp[i][1] = dp[i - 1][0] - prices[i]. - The third situation is that the previous day was in the freezing period ( The freezing period mentioned here is not just before 2 Day sell , Resulting in the freezing period of the previous day , It may have been sold earlier , Then keep it in its state , It is equivalent to the renewal of the freezing period , But you can buy stocks during the renewal ), Now you can buy , namely
dp[i][1] = dp[i - 1][3] - prices[i], amongdp[i][3]Indicates traversing to theiEarnings in the frozen period when stocks are paid . - Combining the above three situations :
d p [ i ] [ 1 ] = m a x ( d p [ i − 1 ] [ 1 ] , m a x ( d p [ i − 1 ] [ 0 ] − p r i c e s [ i ] , d p [ i − 1 ] [ 3 ] − p r i c e s [ i ] ) ) dp[i][1] = max(dp[i - 1][1], max(dp[i - 1][0] - prices[i], dp[i-1][3] - prices[i])) dp[i][1]=max(dp[i−1][1],max(dp[i−1][0]−prices[i],dp[i−1][3]−prices[i]))
- After traversing to the
dp[i][2], Said in the firstiThere are no stocks in your hand when you buy stocks , There are two states that can be transferred to this state :- After traversing to the
i-1When you buy stocks, there are no stocks in your hands , Then we just need to stay in shape , namelydp[i][2] = dp[i - 1][2]. - After traversing to the
i-1When you buy stocks, you have stocks in your hands , Then we need to sell this stock , namelydp[i][2] = dp[i - 1][1] + prices[i]. - Combining the above two situations :
d p [ i ] [ 2 ] = m a x ( d p [ i − 1 ] [ 2 ] , d p [ i − 1 ] [ 1 ] + p r i c e s [ i ] ) dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]) dp[i][2]=max(dp[i−1][2],dp[i−1][1]+prices[i])
- After traversing to the
dp[i][3], Said in the firstiStocks are in the freezing period , This state can only be transferred from one state , That is, there was no stock in hand the day before ( Because I sold ), namelydp[i][3] = dp[i][2].
Initialization and traversal order of array
According to the above analysis, we can know , When traversing the first stock, if you hold the stock, you need to buy , Then the status of buying dp[0][1] The value of is equal to -prices[0], The status income of selling is 0, The state of freezing period is also equal to 0. According to the state transition equation, section i The data of the row depends on i-1 That's ok , So traverse from front to back .
The biggest gain
According to the status we set above , The biggest benefit we can get is dp[prices.length - 1][2], dp[prices.length - 1][3] One of the two , Because in the end, if we want to gain the most, there must be no stocks in our hands , There are two states mentioned above when there is no stock .
m a x ( d p [ p r i c e s . l e n g t h − 1 ] [ 2 ] , d p [ p r i c e s . l e n g t h − 1 ] [ 3 ] ) max(dp[prices.length - 1][2], dp[prices.length - 1][3]) max(dp[prices.length−1][2],dp[prices.length−1][3])
Code
class Solution {
public int maxProfit(int[] prices) {
// dp[i][0] It means that there is no buying or selling operation This value is always equal to 0, You can not use this state
// But in order to be complete, this state is left
// dp[i][1] To hold shares
// dp[i][2] Indicates that you do not hold shares
// dp[i][3] The freezing period after the selling operation
int[][] dp = new int[prices.length][4];
dp[0][1] = -prices[0];
for (int i = 1; i < prices.length; ++i) {
dp[i][1] = Math.max(Math.max(dp[i - 1][1], dp[i - 1][3] - prices[i]),
dp[i][0] - prices[i]); // because dp[i][0] Always equal to 0 So it can be written directly here -prices[i] It's OK
dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
dp[i][3] = dp[i - 1][2];
}
return Math.max(dp[prices.length - 1][2], dp[prices.length - 1][3]);
}
}
because dp[i][0] Always equal to 0, So let's include dp[i][0] Can be deleted , So the following code is also correct .
class Solution {
public int maxProfit(int[] prices) {
// dp[i][0] It means that there is no buying or selling operation This value is always equal to 0, You can not use this state
// But in order to be complete, this state is left
// dp[i][1] To hold shares
// dp[i][2] Indicates that you do not hold shares
// dp[i][3] The freezing period after the selling operation
int[][] dp = new int[prices.length][4];
dp[0][1] = -prices[0];
for (int i = 1; i < prices.length; ++i) {
dp[i][1] = Math.max(Math.max(dp[i - 1][1], dp[i - 1][3] - prices[i]),
-prices[i]);
dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1] + prices[i]);
dp[i][3] = dp[i - 1][2];
}
return Math.max(dp[prices.length - 1][2], dp[prices.length - 1][3]);
}
}
Array optimization —— Scrolling array
In the above state transition equation, we always use only two lines of data , So we can only use a two-dimensional array , Then use it alternately ( Yes i seek 2 The remainder of is enough ) That's all right. , The code is as follows :
class Solution {
public int maxProfit(int[] prices) {
int[][] dp = new int[2][4];
dp[0][1] = -prices[0];
for (int i = 1; i < prices.length; ++i) {
dp[i & 1][1] = Math.max(Math.max(dp[(i - 1) & 1][1], dp[(i - 1) & 1][3] - prices[i]),
dp[i & 1][0] - prices[i]);
dp[i & 1][2] = Math.max(dp[(i - 1) & 1][2], dp[(i - 1) & 1][1] + prices[i]);
dp[i & 1][3] = dp[(i - 1) & 1][2];
}
return Math.max(dp[(prices.length - 1) & 1][2], dp[(prices.length - 1) & 1][3]);
}
}
The best time to buy and sell stocks includes handling fees
subject
Given an array of integers prices, among prices[i] It means the first one i Day's share price ; Integers fee Represents the handling fee for trading shares .
You can close the deal indefinitely , But you have to pay a handling fee for every transaction . If you have bought a stock , You can't buy any more stock until you sell it .
Return the maximum profit .
Be careful : A deal here refers to the whole process of buying, holding and selling stocks , You only need to pay a handling fee for each transaction .
Example
Example 1
Input :prices = [1, 3, 2, 8, 4, 9], fee = 2
Output :8
explain : The maximum profit that can be achieved :
Buy... Here prices[0] = 1
Sell... Here prices[3] = 8
Buy... Here prices[4] = 4
Sell... Here prices[5] = 9
Total profit : ((8 - 1) - 2) + ((9 - 4) - 2) = 8
Example 2
Input :prices = [1,3,7,5,10,3], fee = 3
Output :6
State representation array and state transition equation
This question is actually in Have you ever seen this kind of Dynamic Planning —— Stock problem of state machine dynamic programming ( On ) The second question is very similar , The only difference is that there is a handling fee , The rest is exactly the same .
Now let's analyze how to transfer the state :
dp[i][0]How is the state ofi-1The state of the world has changed :- If the first
i-1One state is that there is no stock in hand , namelydp[i-1][0], So the firstiThere are no stocks in each state , So directlydp[i][0] = dp[i - 1][0], Because there is no transaction . - If the first
i-1There are stocks in the hands of States , namelydp[i-1][1], So if you want toiThere are no stocks in this state , Then you need to sell the stock , Then the income isdp[i-1][1] + prices[i], namelydp[i][0] = dp[i-1][1] + prices[i], But there will be a handling charge in this topic , We need to pay a handling fee when we sell , Then our income becomesdp[i][0] = dp[i-1][1] + prices[i] -fee. - Combining the above two transfer methods, we can get the following transfer equation :
d p [ i ] [ 0 ] = m a x ( d p [ i − 1 ] [ 0 ] , d p [ i − 1 ] [ 1 ] + p r i c e s [ i ] − f e e ) dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i] -fee) dp[i][0]=max(dp[i−1][0],dp[i−1][1]+prices[i]−fee)
- If the first
dp[i][1]How to transfer the state of :- If the first
i-1One state is that there is no stock in hand , namelydp[i-1][0], Then we need to start fromi-1Buy when there are no stocks in your hands , thatdp[i][0] = dp[i - 1][0] - prices[i]. - If the first
i-1There are stocks in the hands of States , namelydp[i-1][1], And the firstiThere are stocks in three states , So there is no need to trade , namelydp[i][1]=dp[i - 1][1]. - Combining the above two transfer methods, we can get the following transfer equation :
d p [ i ] [ 1 ] = m a x ( d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 0 ] − p r i c e s [ i ] ) ; dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]); dp[i][1]=max(dp[i−1][1],dp[i−1][0]−prices[i]);
- If the first
Combine the above two states :
{ d p [ i ] [ 0 ] = m a x ( d p [ i − 1 ] [ 0 ] , d p [ i − 1 ] [ 1 ] + p r i c e s [ i ] − f e e ) d p [ i ] [ 1 ] = m a x ( d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 0 ] − p r i c e s [ i ] ) ; \begin{cases}dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i] -fee)\\ dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]); \end{cases} { dp[i][0]=max(dp[i−1][0],dp[i−1][1]+prices[i]−fee)dp[i][1]=max(dp[i−1][1],dp[i−1][0]−prices[i]);
Code
class Solution {
public int maxProfit(int[] prices, int fee) {
int[][] dp = new int[prices.length][2];
// dp[i][0] Indicates that you do not hold shares
// dp[i][1] To hold shares
dp[0][1] = -prices[0];
for (int i = 1; i < prices.length; ++i) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i] - fee);
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
}
return dp[prices.length - 1][0];
}
}
Array optimization —— Scrolling array
class Solution {
public int maxProfit(int[] prices, int fee) {
int[][] dp = new int[2][2];
// dp[i][0] Indicates that you do not hold shares
// dp[i][1] To hold shares
dp[0][1] = -prices[0];
for (int i = 1; i < prices.length; ++i) {
dp[i & 1][0] = Math.max(dp[(i - 1) & 1][0], dp[(i - 1) & 1][1] + prices[i] - fee);
dp[i & 1][1] = Math.max(dp[(i - 1) & 1][1], dp[(i - 1) & 1][0] - prices[i]);
}
return dp[(prices.length - 1) & 1][0];
}
}
To optimize the
class Solution {
public int maxProfit(int[] prices, int fee) {
int[] dp = new int[2];
// dp[0] Indicates that you do not hold shares
// dp[1] To hold shares
dp[1] = -prices[0];
for (int i = 1; i < prices.length; ++i) {
dp[0] = Math.max(dp[0], dp[1] + prices[i] - fee);
dp[1] = Math.max(dp[1], dp[0] - prices[i]);
}
return dp[0];
}
}
The above code optimization and Have you ever seen this kind of Dynamic Planning —— Stock problem of state machine dynamic programming ( in ) The optimization principle is the same . In the following code , The single row array on the left dp[0] and dp[1] It is equivalent to dp[i][0],dp[i][1], The single row array on the right dp[0] and dp[1] Equivalent to a two-dimensional array dp[i - 1][0] and dp[i - 1][1].
dp[0] = Math.max(dp[0], dp[1] + prices[i] - fee);
dp[1] = Math.max(dp[1], dp[0] - prices[i]);
But we will find that the second line of the above code depends on dp[0], This dp[0] It's No i-1 The state of the line , however dp[0] An update has occurred in the first line , in other words dp[0] Has been updated to page i The state of the line , So why is the result right ? We can analyze according to the following three rules :
- If
dp[0]What is taken isdp[0], in other wordsdp[0] > dp[1] + prices[i] - fee, thatdp[0]Or the status of the previous line , Does not affectdp[1]Result . - If
dp[0]What is taken isdp[1] + prices[i] - fee, howeverdp[1]It's from the previous linedp[1]Then it has no effect on the result . - If
dp[0]What is taken isdp[1] + prices[i] - feeanddp[1]What is taken isdp[0] - prices[i], Then it will have an impact , But this plus and minus is actually meaningless , You simply need to pay a handling fee , Finaldp[0] - prices[i] = dp[1] + prices[i] - fee - prices[i] = dp[1] - fee < dp[1], Therefore, this state will not be taken by the final result , The state taken must be the firsti-1Yesdp[1]( becausedp[1]Bigger ), In other words, this state will shift to the second , Therefore, it has no effect on the final result .
summary
In this article, I mainly introduce the last two stock issues , The state transition of the first question is still relatively complex , You may need to experience it carefully , Can understand , In particular, the transformation of the state during the freezing period may be more convoluted . The second topic in this article is very similar to the previous topic , Just subtract the handling fee from the income . I believe after reading these three articles , After finishing these six questions, you are right State machine dynamic programming The basic principle of has been well understood , The most difference between it and traditional dynamic programming is that there are many complex transitions between States , And the general topic of dynamic programming is multiple cycles , But in State machine dynamic programming There is a single cycle .
More wonderful content collections can be accessed to the project :https://github.com/Chang-LeHung/CSCore
Official account : Worthless research monk , Learn more about computers (Java、Python、 Fundamentals of computer system 、 Algorithm and data structure ) knowledge .
边栏推荐
- 学习Typescript(二)
- 8、 QoS queue scheduling and message discarding
- 二 RedisTemplate的序列和反序列化机制讲解
- Paging function (board)
- 中文招聘文档中专业技能词抽取的跨域迁移学习
- 中国农业工程学会农业水土工程专业委员会-第十二届-笔记
- Why on earth is it not recommended to use select *?
- Why does Baidu search only crawl, but not show the page?
- Log slimming operation: how to optimize from 5g to 1g! (glory Collection Edition)
- 大学荒废三年,大四自学7个月测试,找到了12K的工作
猜你喜欢

软考 --- 数据库(3)数据操作

How to skillfully use assertion + exception handling classes to make the code more concise! (glory Collection Edition)

Construction of Chinese traditional embroidery classification model based on xception TD

Why on earth is it not recommended to use select *?

纳米金偶联抗体/蛋白试剂盒(20nm,1mg/100μg/500 μg偶联量)的制备

基于多模态融合的非遗图片分类研究

LeetCode链表问题——面试题02.07.链表相交(一题一文学会链表)

The ref value ‘xxx‘ will likely have changed by the time this effect function runs.If this ref......

Timing analysis and constraints based on Xilinx

实现瀑布流效果
随机推荐
Another installation artifact
Leetcode linked list problem -- 142. circular linked list II (learn the linked list by one question and one article)
面向千元级5G手机市场,联发科天玑700发布
瑞典法院取消对华为和中兴的5G频谱拍卖禁令
Top level "redis notes", cache avalanche + breakdown + penetration + cluster + distributed lock, Nb
Why on earth is it not recommended to use select *?
Paging function (board)
【英雄哥七月集训】第 28天:动态规划
For the next generation chromebook, MediaTek launched new chipsets mt8192 and mt8195
职场高薪 |「中高级测试」面试题
How to skillfully use assertion + exception handling classes to make the code more concise! (glory Collection Edition)
CVPR 2022 | in depth study of batch normalized estimation offset in network
Ijcai2022 tutorial | dialogue recommendation system
Pytorch学习记录(三):随机梯度下降、神经网络与全连接
中国农业工程学会农业水土工程专业委员会-第十二届-笔记
Several skills of API interface optimization
这种动态规划你见过吗——状态机动态规划之股票问题(下)
怎样巧用断言+异常处理类,使代码更简洁!(荣耀典藏版)
Bus, protocol, specification, interface, data acquisition and control system in industrial communication field
多线程顺序运行的 4 种方法,面试随便问