day46
1、leetcode139 单词拆分
-
问题分析==》完全背包问题
- 背包:字符串s
- 物品:字典中的字符串(每个字符串可重复使用)
-
动规五步法
-
dp[i] :字符串长度为i,若dp[i]为true,则表示可以将该字符串拆分为一个或多个在字典中出现的单词。
-
递归公式
if dp[j]==true && s[i,j] in 字典]: dp[i] = true -
初始化
- dp[i] 由前一个状态推出 =====》dp[0] = true
-
确定遍历顺序
- 要求字典中的字符串要按照一定顺序排列,才能组成字符串s ===》求排列数
- 因此,先遍历背包,再遍历物品
-
举例推导dp[i]
-
-
代码
class Solution { public boolean wordBreak(String s, List<String> wordDict) { boolean[] dp = new boolean[s.length() + 1]; dp[0] = true; for(int j=1; j<=s.length(); j++) {//先遍历背包 for(int i=0; i<j ; i++) {//再遍历物品 if(dp[i]==true && wordDict.contains(s.substring(i, j))) { dp[j] = true; } } } return dp[s.length()]; } }
2、背包总结
- 背包递推公式
- 问能否能装满背包(或者最多装多少):dp[j] = max(dp[j], dp[j - nums[i]]+nums(i))
- 问装满背包有几种方法: dp[j] += dp[j-nums[i]]
- 问背包装满最大价值:dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
- 问装满背包所有物品的最小个数:dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
- 背包顺序
- 01背包
- 二维dp数组
- 先遍历物品还是先遍历背包都是可以的,且第二层for循环是从小到大遍历。
- 一维背包数组(滚动数组)
- 只能先遍历物品再遍历背包容量,且第二层for循环是从大到小遍历。
- 二维dp数组
- 完全背包
- 一维背包数组
- 先遍历物品还是先遍历背包都是可以的,且第二层for循环是从小到大遍历。
- 先遍历物品,再遍历背包 ===》 组合数
- 先遍历背包,再遍历物品 ===》 排列数
- 若求最小数,则两层for循环的先后顺序就无所谓了
- 先遍历物品还是先遍历背包都是可以的,且第二层for循环是从小到大遍历。
- 一维背包数组
- 01背包

浙公网安备 33010602011771号