Java教程

20210822-周总结

本文主要是介绍20210822-周总结,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

周总结

主要是把动态规划的PDF二刷了一遍,巩固基础;各大厂的机试里面考动态规划还是挺多的,掌握好非常重要。

周末学了回溯算法的组合类问题。下周一计划看完回溯;周二~周四学DFS和BFS;周五看贪心;周末总结整理。

背包问题总结

0-1背包

给出n个不同物品,每个物品有重量weight和价格value;给出一个背包,每个背包有最大容量W。每件物品只有一件。

一般有如下题型:

  1. 判断能否将背包刚好装满 or 装满容量为j的背包有几种方法 -- 组合问题

    • 例题:分割等和子集(正好装满sum/2)、目标和(正好装满(sum+S)/2)

    • dp[j] += dp[j - nums[i]]

    • 难点在于如何将题目的条件套用背包问题的框架。

  2. 求解在背包容量的限制下,可以装下的最大价值

    • dp[j] = max(dp[j], dp[j - weight[i] + value[i]])
      
    • 0-1背包的初始化时要注意递推公式中的max后者min,相应的初始化为最小值和最大值。

    • 0-1背包的遍历顺序(滚动数组):先遍历物品,后遍历背包(反过来就会导致每件物品在背包中只放入了一件物品);遍历背包时从后向前遍历(否则每件物品会重复放入)

完全背包

给出N件物品,每件物品有重量weight和价格value;给出一个背包,每个背包有最大容量W。每件物品有无限多件,可以重复放入。

一般有如下题型:

  1. 纯完全背包问题,求最大价值

    纯完全背包,遍历顺序皆可,但是遍历背包要从前向后,保证每件物品多次放入。

  2. 求装满背包的有几种方法

    • 求组合数量:先遍历物品,后遍历背包(为防止同样的组合重复出现);遍历背包时从前向后(保证物品多次放入)

      从前向后遍历背包时,因不能保证背包容量j大于物品重量weight[i],要加判断:j-weight[i] > 0

    • 求排列数量:先遍历背包,后遍历物品(这样重复组合都算进去了);遍历背包也是从前向后(保证物品多次放入)

多重背包

给出N件物品,每件物品有重量weight,价格value,数量nums;给出一个背包,每个背包有最大容量W。每件物品有在数量限制内,可以重复放入。

解题方法就是把不同的数量都展开,变成0-1背包。具体到代码就是在两重for循环内加一层遍历数量的循环。

打家劫舍问题总结

基础打家劫舍

考虑第i房间(dp[i-2]+nums[i]) and 不考虑第i房间(dp[i-1])

打家劫舍:环形房屋

数组成环考虑3种情况:

  1. 不考虑头尾元素
  2. 考虑头不考虑尾
  3. 考虑尾不考虑头

3、2包含1,故而只考虑2种情况。将两种不同的首尾参数传入基础打家劫舍逻辑即可。

打家劫舍:树形dp

后序遍历

买卖股票问题总结

dp[i][0] 表示第i天持有股票所得最大现金;dp[i][1]表示第i天不持有股票所得最大现金。

只能买卖一次

第i天持有股票:

  • 第i-1天就持有了:dp[i-1][0]
  • 第i天刚好买进来:-prices[i]

第i天不持有股票:

  • 第i-1天就不持有:dp[i-1][1]
  • 前面一直持有,到第i天卖了:dp[i-1][0] + prices[i]

最大值出现在dp[-1][1]的时候

可买卖多次

第i天持有股票:

  • 第i-1天就持有了:dp[i-1][0]
  • 第i天刚好买进来:dp[i-1][1]-prices[i]

第i天不持有股票:

  • 第i-1天就不持有:dp[i-1][1]
  • 前面一直持有,到第i天卖了:dp[i-1][0] + prices[i]

最大值出现在dp[-1][1]的时候

限制最多完成两笔交易

分类讨论五种情况:对应dp[i][0-4]

  1. 没有操作
  2. 第一次买入
  3. 第一次卖出
  4. 第二次买入
  5. 第二次卖出

dp[i][1-4] 两个来源:当天发生操作,沿用前一天状态

题目改成最多完成k笔交易,找规律即可

冷冻期

还没搞明白,人傻了

含手续费

没区别,在每次买入or卖出的时候减掉一笔钱就行

这篇关于20210822-周总结的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!