第四部……现在带来经典背包问题……
1、背包问题
来源:lintcode
有 n
个物品和一个大小为 m
的背包. 给定数组 A
表示每个物品的大小和数组 V
表示每个物品的价值.
问最多能装入背包的总价值是多大?
Example
样例 1:
输入: m = 10, A = [2, 3, 5, 7], V = [1, 5, 2, 4]
输出: 9
解释: 装入 A[1] 和 A[3] 可以得到最大价值, V[1] + V[3] = 9
解:以画图的方式呈现上述例子:
现在表格画出来了,首先第一行第一列我们不放东西,当然这也是必要的,行是为了后续进行比较,列是为了对应包的大小,方便编写代码。
列为当前背包的大小,行为物品,每个格子为当前背包大小你能吃饱多少度(每种东西只有一样)。下面开始分析:
辣条:辣条的大小是 2 ,吃饱度为 1,于是在这一行因为只有辣条,所以即使有 10 大小的包,也只能装大小为 2 的辣条,现在你的吃饱度为 1 ,由于背包大小是0 的时候,装不下辣条,所以还是 0 吃饱度。
饼干:注意从这一行开始就要有规律了。饼干的大小是 3 ,吃饱度为 5 。在0、1、2格子中,都装不下饼干,所以吃饱度还是和上一行吃辣条的吃饱度是一样的。在第 3 格子的时候,装的下饼干了,且它的吃饱度是 5 ,大于辣条,于是放弃辣条,装饼干。从第 5 个格子开始,背包大小就大于饼干和辣条的总大小了,于是可以都装下,现在的吃饱度是 6 。表格如下:
薯片:从上一行的规律开始,下面继续,薯片的大小是 2,吃饱度是 2 ,大小和辣条是一样的,但是吃饱度是大于辣条的,于是它顶替了辣条的位置,在第 7 个格子开始,背包大小就大于薯片、饼干和辣条的总大小了,于是都可以装下。
汽水:最后一行了。汽水的大小是 7,是饱度是 4,现在开始前七个格子都是装不下汽水的,所以和上一行是一样的。在第8个格子的时候,刚好能装下但是它的吃饱度没有薯片、饼干和辣条的总吃饱度大,于是放弃。在第 10 个格子的时候,背包大小是 9 。发现背包大小是 2 的时候,吃饱度是 2,加上汽水 7 的吃饱度,是 9 的吃饱度,战胜了薯片、饼干和辣条的组合。于是就是薯片+汽水了。
完结。源代码链接在文章结尾。
2、分割回文串 II
来源:leetcode
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回符合要求的最少分割次数。
示例:
输入: "aab"
输出: 1
解释: 进行一次分割就可将 s 分割成 ["aa","b"] 这样两个回文子串。
解:这道题和前面的单词分割是否在字典中出现是一个道理。我们定义状态 F(i): 到第i个字符需要的最小分割数,首先还需要一个中间变量 j ,j 以前的字符的最小分割数已经计算好了,于是如果从j+1到i判断为回文字符串那么只需要再切一次,就可以保证
1-->j,j+1-->i 的串都为回文串。
两道题源代码:戳我戳我~