Best Time to Buy And Sell Stock II


题目链接:题目描述

这道题我们首先考虑动态规划来写。

定义dp[i][0]为第i天手上没有股票;dp[i][1]为第i天手上持有股票。

那么,考虑dp[i][0]的状态转移方程:这一天没有持有股票,那么有可能前一天也没有持有股票,所以就是dp[i-1][0];也有可能,前一天是持有了股票的,即dp[i-1][1],持有了股票的话,我们就要考虑在第i天把它卖出去,那么我就可以拿到prices[i]的钱,最后二者要取最大值。所以就是dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i]).同理,对于dp[i-1][1]而言,有可能前面那一天我也持有股票;也有可能没有持有,而第i天我是买了股票的,所以要把花钱买prices[i]的股票,所以状态转移方程就是:dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]).

好了,现在我们来看看初始值,那么,第0天没有持有股票,所以dp[0][0] = 0.而dp[0][1],表示第0天就有股票了,这刚开始我肯定是没钱的,所以就是0-prices[i]=-prices[i].

下面是代码:

 1 public int maxProfit(int[] prices) {
 2         int n = prices.length;
 3         int[][] dp = new int[n][n];
 4         dp[0][0] = 0;
 5         dp[0][1] = -prices[0];
 6         for (int i = 1; i < n; ++i) {
 7             dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1]+prices[i]);
 8             dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0]-prices[i]);
 9         }
10         return dp[n-1][0];
11 }

 这样开数组,仔细分析我们会发现其实没有必要,因为每一天的状态都只跟前一天的状态有关。因此我们考虑使用几个变量来代替数组:

代码:

 1 public int maxProfit(int[] prices) {
 2         int profitOut = 0;
 3         int profitIn = -prices[0];
 4         for (int i = 0; i < prices.length; ++i) {
 5             int out = Math.max(profitOut, profitIn+prices[i]);
 6             int in = Math.max(profitIn, profitOut-prices[i]);
 7             profitOut = out;
 8             profitIn = in;
 9         }
10         return profitOut;
11 }

 大功告成!