假设有一个数组 nums,里面存放着每个房屋内的金额:
nums = [1, 2, 3, 1]
现在我们来计算在不触发警报的情况下能够偷到的最高金额。
1.初始化:
我们首先初始化一个数组 dp,用来存放每个房屋能够偷到的最高金额。数组长度为 n + 1,多出的一个元素是为了处理边界情况。
dp = [0, 0, 0, 0, 0]
初始化时,前两个元素都为 0,因为没有房屋可偷,所以偷到的金额为 0。
2.状态转移:
现在我们开始考虑状态转移方程。我们从第一个房屋开始,逐个考虑是否偷取。根据题意,如果连续偷取相邻的两个房屋,则会触发警报。因此,我们需要确保选择的房屋不能相邻。
3.对于第一个房屋,我们有以下选择:
4.偷取第一个房屋,则偷到的金额为 1,因为没有相邻的房屋,不会触发警报。
5.不偷取第一个房屋,则偷到的金额为 0。
综合考虑,偷取第一个房屋得到的金额为 1。
6.对于第二个房屋,我们有以下选择:
7.偷取第二个房屋,则偷到的金额为 2,因为没有相邻的房屋,不会触发警报。
8.不偷取第二个房屋,则偷到的金额为 1。
综合考虑,偷取第二个房屋得到的金额为 2。
9.对于第三个房屋,我们有以下选择:
10.偷取第三个房屋,则偷到的金额为 4(1 + 3),因为前面没有偷取第二个房屋,不会触发警报。
11.不偷取第三个房屋,则偷到的金额为 2。
综合考虑,偷取第三个房屋得到的金额为 4。
12.对于第四个房屋,我们有以下选择:
13.偷取第四个房屋,则偷到的金额为 4(2 + 1),因为前面偷取了第二个房屋,不会触发警报。
14.不偷取第四个房屋,则偷到的金额为 4。
综合考虑,偷取第四个房屋得到的金额为 4。
15.结果输出:
根据计算得到的 dp 数组,最终我们能够偷取到的最高金额为 4。
所以,对于给定的数组 [1, 2, 3, 1],我们最多能偷取到的金额为 4。
c++代码实现
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int rob(vector<int>& nums) {
int n = nums.size();
if (n == 0) return 0;
if (n == 1) return nums[0];
vector<int> dp(n);
dp[0] = nums[0];
dp[1] = max(nums[0], nums[1]);
for (int i = 2; i < n; ++i) {
dp[i] = max(dp[i-1], dp[i-2] + nums[i]);
}
return dp[n-1];
}
int main() {
vector<int> nums = {2, 7, 9, 3, 1};
cout << rob(nums) << endl; // 输出:12
return 0;
}
这段代码定义了一个 rob 函数,接受一个整数数组作为输入,并返回能够偷窃到的最高金额。在 main 函数中,我们给出了一个示例数组 [2, 7, 9, 3, 1],并输出了最高金额 12。