题目
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例 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 。
提示:
1 <= nums.length <= 100
0 <= nums[i] <= 400
代码编写
这道题使用动态规划的思想来解决,声明一个数组dp,用来记录没盗窃一家房屋所能盗窃的最多金额数量即可
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
if(n==0) return 0;
if(n==1) return nums[0];
if(n==2) return max(nums[0] , nums[1]);
vector<int> dp;
dp.push_back(nums[0]);
dp.push_back(nums[1]);
int max;
int ans = nums[0] > nums[1] ? nums[0] : nums[1];
for(int i = 2;i < n;i++){
max = 0;
for(int j = i - 2;j>=0;j--){
if(dp[j] > max){
max = dp[j];
}
}
max = max + nums[i];
dp.push_back(max);
if(max> ans){
ans = max;
}
}
return ans;
}
};
再优化下代码直接使用回滚数组也可以实现
int n = nums.size();
if(n==0) return 0;
if(n==1) return nums[0];
if(n==2) return max(nums[0] , nums[1]);
int f1 = nums[0];
int f2 = max(nums[0] , nums[1]);
int tmp = 0;
for(int i = 2;i < n;i++){
tmp = f2;
f2 = max(f1 + nums[i],f2);
f1 = tmp;
}
return f2;