【DP笔记】二

【DP笔记】二

前言

被两道题虐了,不多说,直接看题吧。。。

题目1:Best Time to Buy and Sell Stock IV

对于该题,确切的说是我按照DP的思路找到一种解法,但是时间复杂度在O(kknnn), 对,你没看错,两个K,三个N,基本不用想,输入数组稍大一点,就会TIMEOUT。先说下基本思路:

  1. 按照标准的DP思路,按段划分
  2. 求得每个分段的第K笔交易的最大值,[0,K]
  3. 最外层是交易次数限制, 控制第2步中的K值

好吧,按我的段位,思路局限于此,再也没法更进一步。加memo、减少循环之类的方法,一直都没找到。不纠结了,找了题解来看,直接把代码贴上吧,此题要不时的复习才行:

public int maxProfit(int k, int[] prices) {
            if (prices.length < 2 || k < 1) {
                return 0;
            }
            if (k >= prices.length/2) {
                int ret = 0;
                int v = 0;
                for (int i = 1; i < prices.length; i++) {
                    v = prices[i] - prices[i - 1];
                    if (v > 0) {
                        ret += v;
                    }
                }
                return ret;
            }

            int[] buys = new int[k + 1];
            int[] sells = new int[k + 1];

            for (int i = 0; i < buys.length; i++) {
                buys[i] = Integer.MIN_VALUE;
            }

            for (int i = 0; i < prices.length; i++) {
                for (int j = 1; j <= k; j++) {
                    buys[j] = Math.max(buys[j], sells[j - 1] - prices[i]);
                    sells[j] = Math.max(sells[j], buys[j] + prices[i]);
                }
            }

            return sells[k];
        }

看到题解也花了我不少时间才消化,再次膜拜其它做出来的大神。

对于k>= len/2的情况,需要特殊处理,这个好理解,相当于不限次数。但是下面循环中的处理,有点绕。

v = prices[i] - prices[i - 1];

if (v > 0) { ret += v;}

这样写,貌似是没有按照买入、卖出的限制来做,其实跳过了多余的判断,因为在[i,j]递增的情况下最大值就是

prices[j] - prices[i],没有中间商赚差价。所以在这种场景下,就是简单的贪心,找到所有的递增序列,求和。

对于k<len/2的情况,更加的抽象。按照buy,sell将每次的交易配对,buy[j]为每次买入后的最大值,sell[j]为每次卖出后的最大值,从代码中能看出最优解是没有问题的。对于我来讲,最大的触动就是,没有按照股票交易模式来做(在a买入,在b卖出,在c买入,在d卖出,abcd必须是不同的价位),而我做DP则很容易受限于题目中的模式限制,不容易跳出限制做抽象。

House Robber II

对于该题,虽然最终我做出来了,但是花的时间比较长,而且题目难度是中,这个对我打击有点大。。。

对于我来讲,这题的难点在于首尾的处理(首尾不能同时存在),即算法要处理最后的最大值中有没有包含位置0的问题;另外一点就是最优解的抽象,最开始使用max(memo[i-1], nums[i] + max(nums[i-2],nums[i-3]))这种方式,这个抽象是错的。

我最终的解决方案,是分场景,要么从0开始,要么从1开始,从0开始的最终结果肯定会包含位置0,这样场景就很明确了;对于最优解的抽象,因为这个是累加的场景,对于i位置,只跟i-3,i-2位置的最大值有关,只有在算最终结果的时候才与i-1位置有关,所以在之前的步骤中,引入i-1反而会出现逻辑上的错误。

总结

做算法一时爽,一直做一直爽。。。但是费时间啊,尤其是难度高的题目,以后得限制一周只花两个晚上的时间搞题目,两晚上搞不出来就看题解,上班了时间不够用啊,得省时间看其他资料呢,切记。。。最后,要复习算法导论里的DP章节,上面的第一题其实就是经典DP算法的一个变形,但是思维受到了限制,导致了做不出的悲剧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值