问题:
买股票问题,给出一个数组,表示某个股票在每一天的价格,
买家可以在一天买入,在之后的一天卖出,一次交易会产生交易费fee,求最大获利。
Example 1: Input: prices = [1, 3, 2, 8, 4, 9], fee = 2 Output: 8 Explanation: The maximum profit can be achieved by: Buying at prices[0] = 1 Selling at prices[3] = 8 Buying at prices[4] = 4 Selling at prices[5] = 9 The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8. Note: 0 < prices.length <= 50000. 0 < prices[i] < 50000. 0 <= fee < 50000.
解法:
动态规划DP
该问题有两种状态:持有该股票的状态repo1,和未持有该股票的状态repo0
在每一种状态下,买家可以选或者不选,即是进行买卖动作or不动作。
则有状态转移方程:
如果在未持有状态:那么可由上一个 未持有状态->不动作 or 持有状态->卖出 得到:
repo0[i]=max{repo0[i−1],repo1[i−1]+prices[i]}
如果在持有状态:那么可由上一个 持有状态->不动作 or 未持有状态->买入 得到:
repo1[i]=max{repo1[i−1],repo0[i−1]−prices[i]−fee}
临界状态:
repo0[0]=0
repo1[0]=不可能,取无限小值
代码参考:
1 class Solution { 2 public: 3 int maxProfit(vector<int>& prices, int fee) { 4 int len=prices.size(); 5 if(len<2)return 0; 6 vector<int> repo0(len+1, 0); 7 vector<int> repo1(len+1, 0); 8 repo0[0]=0; 9 repo1[0]=INT_MIN; 10 int i=1; 11 for(i=1; i<len+1; i++){ 12 repo0[i]=max(repo0[i-1], repo1[i-1]+prices[i-1]); 13 repo1[i]=max(repo1[i-1], repo0[i-1]-prices[i-1]-fee); 14 } 15 return repo0[len]; 16 } 17 };
又可以简化所需要的变量只是上一次的值,因此可转为以下
代码参考:
1 class Solution { 2 public: 3 int maxProfit(vector<int>& prices, int fee) { 4 int len=prices.size(); 5 if(len<2)return 0; 6 int repo0; 7 int repo1; 8 repo0=0; 9 repo1=INT_MIN; 10 int i=1; 11 for(i=1; i<len+1; i++){ 12 int tmp=repo0; 13 repo0=max(repo0, repo1+prices[i-1]); 14 repo1=max(repo1, repo0-prices[i-1]-fee); 15 } 16 return repo0; 17 } 18 };