你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例 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 。
代码
int rob(vector<int>& nums) {
if (nums.size() == 0) {
return 0;
}
int N = nums.size();
vector<int> dp(N+1, 0); //初始化一个数组
dp[0] = 0;
dp[1] = nums[0];
for (int k = 2; k <= N; k++) {
//决定这间房子不偷 或者 偷这个房子并且把上一个的上一个的最大金额加上
dp[k] = max(dp[k-1], nums[k-1] + dp[k-2]);//这里nums的k-1就代表了,第k个房子金额
}
return dp[N];
}
空间优化
class Solution {
public:
int rob(vector<int>& nums) {
int prev = 0;
int curr = 0;
// 每次循环,计算“偷到当前房子为止的最大金额”
for (int i : nums) {
// 循环开始时,curr 表示 dp[k-1],prev 表示 dp[k-2]
//不偷当前房子,保持 curr 的值
//偷当前房子,加上这间房子的金额 i 和上上间房子的最大金额 prev
int temp = max(curr, prev + i);
prev = curr;
curr = temp;
// 循环结束时,curr 表示 dp[k],prev 表示 dp[k-1]
}
return curr;
}
};