股票的最大利润

目录

思路一

思路二----动态规划


题目描述

注意本题的只可以交易一次的这个条件 

思路一

贪心算法:每一次记录到当前[0,i]之间的最小值,然后用当前prices[i]-min_price,迭代记录即可.


class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int min_price = 1e+7;
        int res = 0;
        for (int i = 0; i < prices.size(); ++i) {
            min_price = min(prices[i], min_price);
            res = max(res, prices[i] - min_price);
        }
        return res;
    }
};

思路二----动态规划

我当时做题时就是想不通---dp数组如何能够表明三种动作,保存,卖出,买入........(dp不应该用来保存动作,应该用来保存状态)

关键点:dp数组表示的是状态,状态只有两种:拥有和未拥有,就像女朋友一样(doge),我们使用dp[i][0]表示当前未拥有股票时的最大利润,dp[i][1]表示当前拥有股票的最大利润.

dp[i][0]可能是由两种情况变化而来,dp[i-1][0],之前就没拥有,dp[i-1][1]之前拥有,但是现在失去了.

dp[i][1]可能是由两种情况变化而来,dp[i-1][1],之前就有,dp[i-1][0],昨天没有,今天就有了.

就这样我们确定了dp的含义,递推公式,递归顺序是从前到后,第四步初始化dp[0][0]=0,dp[0][1]=-prices[0].第五步,手动推导dp数组.

就这样,代码就写好啦!

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        vector<vector<int>> vec(prices.size(), vector<int>(2,0));       //(hang,vector<int>(lie,val))
        vec[0][0] = 0;      //不持有股票
        vec[0][1] = -prices[0];     //持有股票
        for (int i = 1; i < prices.size(); ++i) {
            vec[i][0] = max(vec[i - 1][0], prices[i] + vec[i - 1][1]);      //今天没有股票
            vec[i][1] = max(vec[i - 1][0] - prices[i], vec[i - 1][1]);      //今天拥有股票
        }
        return max(vec[prices.size() - 1][0], vec[prices.size() - 1][1]);
    }
};  

但是这代码有什么问题?它最大的问题在于没有限制说只能购买一次.它可以解决LeetCode122题

那么如何修改使其只能购买一次呢?

 第i天买入股票,只能买入一次,那么就不能用之前的max(vec[i-1][0]-prices[i],vec[i-1][1])

vec[i-1][0]表示之前不知道多少次买卖后,失去股票时的最大利润,我们去掉这一项,只留下-prices[i],那么只表示当前买或者之前买,哪一次买的最便宜,就留下哪一次.


class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.size() <= 1)    return 0;
        vector<vector<int>> vec(prices.size(), vector<int>(2,0));       //(hang,vector<int>(lie,val))
        vec[0][0] = 0;      //不持有股票
        vec[0][1] = -prices[0];     //持有股票
        for (int i = 1; i < prices.size(); ++i) {
            vec[i][0] = max(vec[i - 1][0], prices[i] + vec[i - 1][1]);      //今天卖掉股票
            vec[i][1] = max(- prices[i], vec[i - 1][1]);      //今天买入股票
        }
        return max(vec[prices.size() - 1][0], vec[prices.size() - 1][1]);
    }
};  

 其实和上面的贪心算法思想是一样的.

小结

1.dp数组表示的是状态而不是动作

2.状态转移方程要明确转移的到底是什么状态,考不考虑之前状态的影响(vec[i-1][0]+prices[i]),还是只考虑当前状态(-prices[i]). 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shallow_Carl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值