打家劫舍
1. 打家劫舍Ⅰ
1.1 题目描述
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两件相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表房屋存放金额的非负整数数组,计算你不触动警报装置的情况下,一夜之内能够偷窃到的最高金额。
【示例1】
输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4
【示例2】
输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
来源:力扣(LeetCode)
【提示】
1 <= nums.length <= 100
0 <= nums[i] <= 400
1.2 动态规划步骤分析
- (1)确定状态
f[i]
:考虑下标i(包括i)
以内的房屋,最多可以偷窃的金额为f[i]
。
- (2)转移方程
- 决定f[i]的因素就是第i间房屋偷不偷。
- 若偷:则
f[i] = f[i-2] + nums[i];
第i-1
间房屋肯定是不考虑的,找出 下标i-2(包括i-2)以内的房屋,最多可以偷窃的金额为
f[i-2]加上第
i`房间偷到的钱 - 若不偷,则
f[i] = f[i-1]
,即考虑i-1
房,并不是一定要偷
- 若偷:则
- 取两者的最大值即为转移方程:
f[i] = max(f[i-1],f[i-2]+nums[i])
;
- 决定f[i]的因素就是第i间房屋偷不偷。
- (3)初始化
- 由递推公式
f[i] = max(f[i-1],f[i-2]+nums[i])
知,递推公式的基础是f[0]和f[1]。
- 由递推公式
从定义上来说
vector<int> f(nums.size());
f[0] = nums[0];
f[1] = max(nums[0],nums[1]);
- (4)计算顺序
- 从前到后
1.3 C++实现
int rob(vector<int>& nums){
if(nums.size() == 0) return 0;
if(nums.size() == 1