198. 动态规划:偷马
一、原题
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
二、题意
假设你是一个专业的偷马贼,街上有一排房子,房子系着一匹马,每匹马都有明确的价格。你在偷马的时候需要注意的是不能偷连续的两匹马(会触发警报),问如何才能偷到最大数目利益。
三、思路
假设有这样一排马:nums = [1, 5, 6, 2, 5, 0, 5, 2, 5, 9, 0]
- 假设只有一匹马,则最大利益为nums[0] = 1;
- 假设有两匹马,则只能偷一匹马,则偷单匹最大利益的nums[1] = 5;
- 假设有三匹马,则先考虑第三匹马,第三匹马有两种情况:偷和不偷。
- 如果不偷,则此时利益就为前两匹马的最大利益;
- 如果偷,则第二匹马不能偷,则此时的利益就是第三匹马的利益与第一匹马的利益;
- 比较两种情况,则最大利益则为有三匹马的最大利益;
- 假设有四匹马,则先考虑第四匹马,同样是两种情况:偷和不偷。
- 假设不偷,则此时的利益就为偷前面三匹马的最大利益;
- 假设偷,则最大利益则为第四匹马的利益与偷前两匹马的利益之和;
- 比较两种情况,则最大利益则为有四匹马的最大利益;
- 同比类推
- 用数组dp用来记录最大利益,则dp[n]则为前n匹马的最大利益,由以上的推理过程可以得知:
dp[n] = max(dp[n-1], dp[n-2] + nums[n])
四、代码
class Solution {
public:
int max(int a, int b){
return a > b? a : b;
}
int rob(vector<int>& nums) {
if(nums.empty()) return 0;
vector<int> maxProfit;
int ifRob, notRob;
for(int i = 0 ; i < nums.size(); ++i){
ifRob = nums[i] + (i >= 2 ? maxProfit[i - 2] : 0);
notRob = i >= 1 ? maxProfit[i - 1] : 0;
maxProfit.push_back(ifRob > notRob ? ifRob : notRob);
}
return maxProfit[nums.size() - 1];
}
};