L4_动态规划
背包问题
枚举的时候,dp[i][w]里w只能由特定的数字得到,因此不需要从0开始枚举所有w的情况,比如由放入1,2,5的硬币得到:d[i][w]=min(d[i],d[i][w-1/2/5].注意这里和区间型的差别,区间型d[i][j]需要枚举所有的j。
如果是第一种问法,要求恰好装满背包,那么在初始化时除了f[0]为0其它f[1..V]均设为-∞,这样就可以保证最终得到的f[N]是一种恰好装满背包的最优解。
如果并没有要求必须把背包装满,而是只希望价格尽量大,初始化时应该将f[0..V]全部设为0。
状态表示前i件物品放入一个容量为ω的背包可以获得的最大价值。
用value或weight做第二个Index,分拿和不拿状态,选个Max.value和weight那个小选哪个做Index
重复和非重复唯一区别就是拿时候从i+1个状态里选还是i个状态里选。重复的话可以包含当前i+1,不重复不能包含i+1
可重复:拿时候从前i+1个选
不重复:拿时候从前i个选
01背包问题:
V倒序才能拿到f[i-1][v]的 否则就是f[i][v]
Palindrome Partitioning II
i,j关系。j相当于i-1。i: 1->n j: 0->i(不含i)
数组分组问题
maximum subarray
split array largest sum
从palindrome I II和word break I II可知 sequence dp
DP问题:https://zhengyang2015.gitbooks.io/lintcode/house_robber_392.html
总结
1需要返回List的结果,dp不明显,考虑一个dp和一个辅助Parent list来求解
2 记忆化搜索从大到小的dp,无法从小开始,直接从总结果最大开始。2个loop区间[i.j]然后一个loopk拆分区间[i.j]。分治思想:stone game,burst balloon
3 排列组合的公式可以用,当需要计算总选择数:Paint Fence,Count Numbers with Unique Digits
4 有环时候去头或者尾,做完再比较哪个大:House Robber II
5 设置2个状态,2个状态交替由对方得到。Wiggle Subsequence, Longest Turbulent Subarray
6 区间循环
7 字串长度 = unique substring数: Unique Substrings in Wraparound String
8 前两天得到第三天的,python可以同时赋值:Delete and Earn,house robber, Paint Fence
或者是一个pos有2个状态,比如min,max(Maximum Product Subarray),类似5
9 状态类dp,一个人可以有多个选择,can I win, Campus Bikes II. 用bit数组来表示每个人的状态。dp[i][bit status] (bit status = 1<< j]
10 博弈类问题
一头取就一维dp,2头取就二维DP(predict the winner),任意取就bit表示状态。 最后决定输赢看sum>0
maxmin问题,最大化自己,最小化对手
11 只和前面某个词有关的,和LIS,如果是和前面几个数有关的,比如fibonacii,等比数列,或者山峰最长长度。以2个数取出来,然后往后顺次找序列。
LIS和Russian doll,都可以用数组bisect.bisect_left找出Index做,原因是每个当前i都要和前面所有0-i比较找出自己位置。比前面都大就res++,否则插入前面位置,等于更新dp里那个位置时候最大的数。
或者2个数出来,根据diff去后面list找第三个数字是否存在。
13 背包 01背包要求满,初始化为infinite 因为都不满开始。不求满求最优,初始0因为有valid值
12 做不出来的时候考虑top down,dfs的分治法,对比dp的bottom up
13 飞机问题 :Cheapest Flights Within K Stops
DFS+MEMO VS DP
DFS pros易理解,cons太深易爆栈,DP pros 可以用滚动数组节约空间
Last updated