题目描述
这题一看就知道得用动态规划做,本来在学校是学过的,但缺少实践,理论知识也忘得差不多了,看到这题还是不知道该怎么用dp解,只能翻看题解,理解后独立写出代码
dp方程如下:
dp[i] = max(dp[i-2] + nums[i] , dp[i-1])
- dp[i]表示偷了 i 家时,获得的最大收益
- nums[i]表示当前准备偷的房屋有多少钱
理解下来就是:偷了 i 家后,我所获得的最大收益要么等于偷完上一家的收益(不偷当前这家),要么等于偷完i-2家和当前房屋的金额之和(偷当前这家)
int rob(vector<int>& nums) {
if(nums.size() == 0) return 0;//没有房屋
if(nums.size() == 1) return nums[0];//只有一间房屋
int len = nums.size();
vector<int> dp(len);
dp[0] = nums[0];//偷了第0家
for(int i=1; i<len; i++){
if(i == 1){
dp[i] = max(nums[i] , dp[i-1]);//偷第1家
}else{
dp[i] = max(dp[i-2] + nums[i] , dp[i-1]);
}
}
return dp[len-1];
}
优化一下,可以去掉dp数组。由于dp数组只是记录了当前获取的最大收益,找个变量记录一下即可。当然上述代码中的dp[i-2]也得用变量记录
int rob(vector<int>& nums) {
if(nums.size() == 0) return 0;
if(nums.size() == 1) return nums[0];
if(nums.size() == 2) return nums[0] > nums[1] ? nums[0] : nums[1];//只有两个房屋时
int len = nums.size();
int cur_profit;
int pre_2 = nums[0];//dp[i-2]
int pre_1 = nums[0] > nums[1] ? nums[0] : nums[1];//dp[i-1]
for(int i=2; i<len; i++){
cur_profit = max(pre_2 + nums[i] , pre_1);
pre_2 = pre_1;
pre_1 = cur_profit;
}
return cur_profit;
}