一道题看清动态规划的前世今生(一)

本文通过一道简单的抢劫房子问题,深入浅出地介绍了动态规划的概念。从暴力搜索和记忆化搜索的角度,阐述动态规划的原理,并揭示其与递归的关系,帮助读者理解动态规划的最优子结构和无后效性特点。
摘要由CSDN通过智能技术生成

@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;
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值