动态规划记录

感觉dp用途有

1、设重量值=价值值,看能不能凑到这个target,dp[len]==taget

2、有dp[i][j]种方法,就像地图路径, 同时也就是需要考虑容量和数量之间的关系的时候

139.单词拆分

这道题有点难理解,刚开始看解析,感觉集合里只要有能够切分的字符串,就会为dp[]=true,导致错误,但是好像我理解错了,有多组的拆分方式也可以

这里不能先遍历物品,是因为比如a+b+a的字符串,先遍历物品a,只有第一个a后面是true,然后再加入物品b,这时候b物品后面是true,但是已经无法更新到最末尾,答案会出错

122.买卖股票的最佳时机II

感觉股票买卖这里,解析很好懂,但是总感觉没有理解透彻,1、为什么刚开始思考会需要两种状态,就像打家劫舍那边一维的就不需要两种状态,这里接不接直接可以算出来,然后取最大值。但是树形的那边为什么又要两种,因为左子树和右子数的结果共同影响当前节点,所以不是一维的取或者不取可以解决的。买卖股票的最佳时机I这里智买卖0次或者一次,就算最后的时间点不持有就可以了,但是前面的持有的时间点并且买入的,一定是唯一一次买入点,所以是-prices[i],这题为什么要两种状态呢,如果和打家劫舍那样每一个点取max(持有和不持有),但是后面推dp的时候,就没得推了,依赖的就是前面持有或者不持有,这里和打家劫舍的加不加入当前的数字不同,情况更复杂一些,所以递推也不同

123.买卖股票的最佳时机III

限制两次买卖,所以比一次或者无线多次多了需要记录的第二次买卖状态,第二次的买卖是从第一次卖出的状态推出的,刚开始有的第二天状态疑惑解析写的很好:第二次买入依赖于第一次卖出的状态,其实相当于第0天第一次买入了,第一次卖出了,然后再买入一次(第二次买入),那么现在手头上没有现金,只要买入,现金就做相应的减少。

309.最佳买卖股票时机含冷冻期

自己做的时候忽略了不持有股票的区别,就是当天卖出还是维持前面的卖出,也就是要区分当天是卖出第二天的冷冻期,还是前一天是冷冻期的不持有股票状态,解析会更细致一些

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        vector<vector<int>> dp(prices.size(), vector<int>(3, 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][2]-prices[i]);
            dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i]);
            dp[i][2] = max(dp[i-1][2], dp[i-1][1]);
        }
        return max(dp[prices.size()-1][1], dp[prices.size()-1][2]);
    }
};

714.买卖股票的最佳时机含手续费

这道题好想一点,不过刚开始初始化的不持有股票,我想成之前的买入再卖出=-fee了,其实对初始化也考虑一下最优,=max(没有买入,当天买入再卖出)

1143.最长公共子序列

看到题目我想到之前做的一维的严格递增的时候,因为不用连续所以需要遍历来找到接着前面的谁去连续这个递增序列,自己做的时候,知道是从左上角的最大值进行推导当前点的答案,但是自己有点der,有点不知道怎么记录得到左上角的最大值,看了答案知道每次都是存储三个方向的最大值,下一次就可以直接利用相邻的获得最大值了,这时候要根据当前字符是不是相等决定要不要加1

115.不同的子序列

这题和1143.最长公共子序列有点关系,最长公共子序列,两个序列都可以删除元素,所以当前的递推可以从三个方向退出来,如果当前元素相同,那么当前最大的子序列一定是[i-1][j-1]+1(想想排除其他情况,匹配的个数最多是相同),而不相同的话最大就是上面和左边的推导,

([i-1][j]  [i][j-1])这两个本来就是从[i-1][j-1]推来得了,就不必再判断一次中间方向了。这道题是目标子串,所以推导的方向不能是删除目标子串了,dp的含义也变了,是能够匹配的次数,和路径思想一样,要把不同方向来的推导方式都加起来等于当前的方式数量,所以有两种匹配方式,如果当前元素相同的话,就是目标子串和匹配串当前下标-1,然后匹配的方式数,就是前面的目标子串匹配的方式,然后我加了一个元素加在两个串的后面,刚好又一样,所以和现在这个下标加了1的匹配方式数量和之前一样,还有一个方向就是删除匹配串当前字符,也能和当前的目标子串匹配的方法

583. 两个字符串的删除操作

这里我的做法是计算最长功能子序列,除了公共子序列外都是要删除的

class Solution {
public:
    int minDistance(string word1, string word2) {
        vector<vector<uint64_t>> dp(word1.size()+1, vector<uint64_t>(word2.size()+1, 0));
        for(int i=1;i<=word1.size();i++){
            for(int j=1;j<=word2.size();j++){
                if(word1[i-1] == word2[j-1]){
                    dp[i][j] = dp[i-1][j-1]+1;
                }else{
                    dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
                }
            }
        }
        return word1.size()+word2.size()-dp[word1.size()][word2.size()]*2;
    }
};

72. 编辑距离

这道题和上一道有相似的地方,但是我上道题偷懒了,虽然有删除和增加两个操作,但是为了达到两个串一样,这两个操作是等价的,相比于上一题,多了一个替换,所以不相同的时候,把其中一个替换成另一个,也是一个推导的方向来源

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值