121.买卖股票的最佳时机
思路:只能购买一次股票,确定dp数组及其下标含义dp[i][0]表示第i天持有股票的最大钱数,dp[i][1]表示第i天不持有股票的最大钱数,递推公式,第i天不持有股票的最大钱数有两种情况,1、第i天卖出了股票,dp[i-1][0]+prices[i],2、第i天之前没买股票,第i天也不买,dp[i-1][1],所以dp[i][1]=max(dp[i-1][0]+prices[i],dp[i-1][1]); 第i天持有股票的最大钱数也有两种情况,1、第i天买入股票:-prices[i],第i 天之前买入了股票,dp[i-1][0]。dp[i-1][0] = max(-prices[i],dp[i-1][0]). 初始化,第0天持有股票dp[0][0] = -prices[0].第0天不持有股票 dp[0][1] = 0; 遍历顺序,从前往后。 打印dp数组,可以用于debug。
class Solution {
public:int maxProfit(vector<int>& prices) {//确定dp数组及其下标的含义 dp[i][0] 表示第i天持有股票的最大钱数, dp[i][1]表示第i天不持有股票的最大钱数//递推公式 dp[i][0] = max(-prices[i],dp[i-1][0]); //当前天持有股票的最大钱数,为前一天持有股票的钱数,与今天才开始买股票的钱数的最大值//递推公式 dp[i][1] = max(dp[i-1][0]+prices[i],dp[i-1][1]); //当天不持有股票的最大钱数,为前一天持有股票钱数,今天卖了,与前一天就不持有,今天也不买的最大值//初始化 dp[0][0]=-prices[0]; 第一天就持有股票//dp[0][1] = 0;第一天不持有股票//遍历顺序,从小到大//打印dp数组,可以用于debugint size = prices.size();vector<vector<int>> dp(size,vector<int> (2,0));dp[0][0] = -prices[0];for(int i = 1;i<prices.size();i++){dp[i][0] = max(-prices[i],dp[i-1][0]);dp[i][1] = max(dp[i-1][0]+prices[i],dp[i-1][1]); }if(dp[prices.size()-1][1]>=0){return dp[prices.size()-1][1];}else{return 0;}}
};
122.买卖股票的最佳时机 II
思路:这道题与当一题的区别在于可以多次购买股票,这道题用贪心算法,计算每天的利润值,求正数的和也可以得到。动态规划的思想与上一题相同,但递推公式不同,因为可以多次购买股票,因此,第i天持有股票的最大金额有两种情况:1、前一天不持有股票,今天刚买。dp[i-1][1]-prices[i]。2、前一天持有股票,今天不买 dp[i-1][0] = max( dp[i-1][1]-prices[i],dp[i-1][0]).第i天不持有股票也有两种情况:1、前一天持有股票,今天卖出.dp[i-1][0]+prices[i].2、前一天不持有股票,今天也不买,dp[i-1][1];dp[i][1] = max(dp[i-1][0]+prices[i],dp[i-1]); 主要区别在于第i天持有股票的最大金额的递推公式,因为上一题只能买一次,所以之前不买股票的本金就是0,今天买了,就直接-prices[i],而此题可以多次买卖,当前买股票时,之前经历过买卖,手中的本金为dp[i-1][1]。
lass Solution {
public:int maxProfit(vector<int>& prices) {int size = prices.size();vector<vector<int>> dp(size,vector<int> (2,0));dp[0][0] = -prices[0];for(int i = 1;i<prices.size();i++){dp[i][0] = max(dp[i-1][0],dp[i-1][1]-prices[i]);dp[i][1] = max(dp[i-1][1],dp[i-1][0]+prices[i]);}return dp[prices.size()-1][1];}
};
收获:
只能买一次和多次的区别就在于,买股票时手里的本金是0还是之前买卖过股票后的金额、