Kyyyyyy 动态规划入门 简单到噗噗捏捏题
Problem_link: 213. 打家劫舍 II
文章目录
- 前言
- 思路
- 解题方法
- 复杂度
- Code
前言
偷东西是不对的
思路
思路和打家劫舍普通差不多,只是多了一个头尾不能同时偷的条件,既然这样,就遍历两次,第一次不管第一家,第二次不管最后一家。
解题方法
- 边界
l e n ( n u m s ) < = 3 len(nums)<=3 len(nums)<=3时,只能选一家,所以挑最大的选就行了。代码是可以处理2家以上的情况的,这样直接返回略快一些。
- 定义状态
每家我们都有偷和不偷两种情况:
- 如果偷,它的前一家就不能偷,结果就等于前一家不偷的情况加上这家的金额。
- 如果不偷,结果就是前一家偷和前一家不偷两种情况中的最大值。
所以, d p [ i ] [ 0 o r 1 ] dp[i][0\ or\ 1] dp[i][0 or 1]表示第i+1家(i从0开始)偷(1)和不偷(0)两种情况的最优解。
{ d p [ 0 ] [ 0 ] = 0 第一家不偷 d p [ 0 ] [ 1 ] = n u m s [ 0 ] 第一家偷 d p [ i ] [ 0 ] = m a x ( d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 0 ] ) 不偷这一家 d p [ i ] [ 1 ] = d p [ i − 1 ] [ 0 ] + n u m s [ i ] 偷这一家 \begin{cases} dp[0][0] = 0 & 第一家不偷 \\ dp[0][1] = nums[0]& 第一家偷 \\ dp[i][0] = max(dp[i-1][1],dp[i-1][0])& 不偷这一家 \\ dp[i][1] = dp[i-1][0]+nums[i] & 偷这一家 \end{cases} ⎩ ⎨ ⎧dp[0][0]=0dp[0][1]=nums[0]dp[i][0]=max(dp[i−1][1],dp[i−1][0])dp[i][1]=dp[i−1][0]+nums[i]第一家不偷第一家偷不偷这一家偷这一家
- 首尾问题
遍历两次,让首尾不同时出现就可以解决。 - 最终结果
把两次遍历的结果都做最大值比较,结果就出来了。
复杂度
时间复杂度:
O ( n ) O(n) O(n)空间复杂度:
O ( n ) O(n) O(n)
Code
int max(int a,int b){return a>b?a:b;
}
// 偷家范围
int robRange(int* nums, int start, int end) {// 对第i个房子偷和不偷,0是不偷,1是偷int dp[100][2] = {{0}};dp[start][0] = 0;dp[start][1] = nums[start];for (int i = start+1; i < end; i++) {dp[i][0] = max(dp[i-1][0],dp[i-1][1]);dp[i][1] = dp[i-1][0]+nums[i];}return max(dp[end-1][0],dp[end-1][1]);
}
int rob(int* nums, int numsSize){// 边界if(numsSize<=3){int res = nums[0];for(int i=1;i<numsSize;i++){res = max(res,nums[i]);}return res;}// 不管第一家的结果和不管最后一家的结果进行比较return max(robRange(nums,1,numsSize),robRange(nums,0,numsSize-1));
}
可以发现每次只使用上一次偷家状态
,所以可以将空间优化为常量。
class Solution:def rob(self, nums: List[int]) -> int:# 边界if(len(nums)<=3):return max(nums)def robRange(nums: List[int],start,end) ->int:# 偷上一家stealFami = nums[start]# 不偷上一家notstealFami= 0# 偷这一家notstealThisFami=None# 不偷这一家stealThisFami =Nonefor i in range(start+1,end):notstealThisFami = max(stealFami,notstealFami)stealThisFami = notstealFami+nums[i]stealFami,notstealFami = stealThisFami,notstealThisFamireturn max(stealFami,notstealFami)return max(robRange(nums,1,len(nums)),robRange(nums,0,len(nums)-1))
Kyyyyyy 动态规划入门 简单到噗噗捏捏题相关推荐
- LQ训练营(C++)学习笔记_动态规划入门
动态规划入门 五.动态规划入门 1.动态介绍 1.1动态规划基本思路 1.2 动态规划基本概念 1.2.1 阶段 1.2.2 状态 1.2.3 决策 1.2.4 状态转移方程 1.2.5 策略 1.3 ...
- 动态规划入门看这篇就够了,万字长文!
今天是小浩算法 "365刷题计划" 动态规划 - 整合篇.大家应该期待已久了吧!奥利给! 01 PART 动态规划是啥 我们把要解决的一个大问题转换成若干个规模较小的同类型问题,当 ...
- 动态规划入门到熟悉,看不懂来打我啊
动态规划入门到熟悉,看不懂来打我啊 兔子hebtu666 本文链接:https://blog.csdn.net/hebtu666/article/details/100585136 2.1斐波那契系列 ...
- 变种 背包问题_动态规划入门——传说中的零一背包问题
今天是周三算法与数据结构专题的第12篇文章,动态规划之零一背包问题.在之前的文章当中,我们一起探讨了二分.贪心.排序和搜索算法,今天我们来看另一个非常经典的算法--动态规划.在acm-icpc竞赛领域 ...
- JMeter压测入门简单使用
JMeter压测入门简单使用. 下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache//jmeter/binaries/apache-jmeter-5.2. ...
- c++ 多重背包状态转移方程_动态规划入门——详解经典问题零一背包
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是周三算法与数据结构专题的第12篇文章,动态规划之零一背包问题. 在之前的文章当中,我们一起探讨了二分.贪心.排序和搜索算法,今天我们来 ...
- 【动态规划】简单背包问题II
问题 J: [动态规划]简单背包问题II 时间限制: 1 Sec 内存限制: 64 MB 提交: 127 解决: 76 [提交] [状态] [讨论版] [命题人:admin] 题目描述 张琪曼:& ...
- 动态规划入门之国王的金矿
最近学习算法,对动态规划不太了解,使用的时候照搬转移方程式,知其然不知其所以然,今天看到一篇动态规划的教程,解释得非常通俗,原文在这里[动态规划入门教程] (http://blog.csdn.net/ ...
- 很特别的一个动态规划入门教程
很特别的一个动态规划入门教程 今天在网上看到一个讲动态规划的文章,是以01背包为例的,这文章和书上的讲解非常不一样,令我眼前一亮,于是转载一下下--- (说明一下,本人非常痛恨教材公式定理漫天飞,实际 ...
最新文章
- 基于matlab的离散系统时域分析实验,《信号与系统》 实验一 信号的时域分析及Matlab实现...
- 二级域名怎么设置_怎么建设自己的网站?看完这四个步骤你就明白了
- WSDL SOAP 绑定
- 配置IntelliJ IDEA
- 采用单/双缓冲区需要花费的时间
- mongodb mongoose 的使用
- “高定美学”品牌矩阵:「莲玉芳华」「琢我」「佐我」佐我气运系列之进击
- 豌豆荚Hack Day:百宝袋负责人访谈
- 微信朋友圈图片显示缩放
- XMind 2021 Mac 去水印教程
- 网上咋打印?网上打印资料文件的平台有哪些
- 零基础入门金融风控-贷款违约预测_Task1
- DataWorks数据建模 - 一揽子数据模型管理解决方案
- cs224n学习笔记 03:Subword Models(fasttext附代码)
- Git入门到精通(大全)
- 计算机-IEEE ACCESS-论文投稿上岸经验分享
- 医学图像处理与分析:现有的各种医学成像手段及其优缺点
- Java程序 CPU使用率过高怎么办?
- 某IDC数据中心智能布线系统案例简析
- 计算机中硬盘上删了的东西为什么还可以恢复sd卡可以吗,怎么从SD卡中恢复误删文件...