@author: StormMa
@date 2017-11-11
生命不息,奋斗不止
前言
本篇文章旨在用通俗简单的语言来教你入门动态规划。动态规划是算法中很重要的一块内容,在各大公司的笔试算法中占据大壁江山,所以,掌握动态规划是你拿到称心的offer的前提,废话不多说,让我们来开始一段算法之旅吧。在开始之前,你要努力忘掉你理解的动态规划,因为有可能那些都是错误的,会限制你的思路。相信我,读完这篇文章你肯定会有收获。
前导技能
- 递归 (熟悉递归运行原理)
- 暴力搜索
- 在线的智商
问题引入
在开始后续的工作之前,我们先来看一道非常简单的题目
题目
题目来源Leetcode
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
题意很简单,我也就不翻译了。
跟着下面的步骤,仔细思考,在这之前,忘掉你对动态规划的理解!
暴搜,动态规划的前生
我假设你具备了我说的那些前导技能,相信你是一个暴搜出奇迹的天才。
那么,我们现在用暴力搜索来分析一下这道题目
现在,我们从最后一个商家开始,搜索我们想要的答案
那么我们现在应该有这样一个函数,假设它具备暴力搜索的功能。那么,我们首先返回已经”完成”的暴力搜索到的答案
java版
private int search(int i, int[] nums) {
...
}
public int rob(int[] nums) {
return search(nums.length - 1, nums);
}
python版
def search(self, i, nums):
pass
def rob(self, nums):
return self.search(len(nums) - 1, nums)
现在,我们”基本”上已经完成了这道题目,因为暴搜对你来说很简单。其实上面这些文字,我只是在教你如何思考题目。接下来,让我们来完成暴搜的主体部分吧!
依据题意,我们不能盗窃相邻的商家,那么问题很简单了。搜索的状态只有两种,我们盗窃当前商家,然后跳过前面一个,继续判断前面的前面那家商家,或者我们不盗窃当前商家,往前走,因为前面有好家伙!这样,我们应该很容易完成search
里面的内容
java版
private int search(int i, int[] nums) {
if (i < 0) { // 没有商家了,我们要开始销赃
return 0;
}