题解:
LintCode 炼码 - ChatGPT!更高效的学习体验!
明确了「状态」和「选择」:你面前房子的索引就是状态,抢和不抢就是选择。
明确了状态转移,就可以发现对于同一 start
位置,是存在重叠子问题的,比如下图:
class Solution {
public:
int rob(vector<int>& nums) {
int begin = 0;
// memo表示从下标开始到末尾nums.size()-1,最高金额
vector<int> memo(nums.size(), -1);
return dfs(nums, begin, &memo);
}
// 表示从begin开始,到nums.size()-1的最高金额
int dfs(const vector<int>& nums, int begin, vector<int>* memo) {
if(begin >= nums.size()) {
return 0;
}
// 记忆化搜索
if((*memo)[begin] != -1) {
return (*memo)[begin];
}
int result = max(dfs(nums, begin+2, memo)+nums[begin], dfs(nums, begin+1, memo));
// 记录
(*memo)[begin] = result;
return result;
}
};
class Solution {
public:
/**
* @param a: An array of non-negative integers
* @return: The maximum amount of money you can rob tonight
*/
long long houseRobber(vector<int> &a) {
// write your code here
// 前面选择几个房子,不一定选择当前的位置
if (a.size() <= 0) {
return 0;
}
std::vector<long long> dp(a.size()+1, 0);
dp[1] = a[0];
for (int i = 2; i <= a.size(); ++i) {
dp[i] = max(dp[i-1], dp[i-2] + a[i-1]);
}
return dp[a.size()];
}
};