打家劫舍
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例 1:
代码语言:javascript复制输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 3 = 4 。
示例 2:
代码语言:javascript复制输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 9 1 = 12 。
提示:
0 <= nums.length <= 100
0 <= nums[i] <= 400
class Solution {
private:
int tryRob( vector<int> &nums, int index ) {
if ( index >= nums.size() )
return 0;
for( int i = index; i < nums.size(); i )
res = max( res, nums[i] tryRob(nums, i 2) );
return res;
}
public:
int rob(vector<int>& nums) {
return tryRob(nums, 0);
}
};
记忆化搜索
代码语言:javascript复制class Solution {
private:
// memo[i] 表示考虑抢劫 nums[i..n]所能获得的最大收益
vector<int> memo;
int tryRob( vector<int> &nums, int index ) {
if ( index >= nums.size() )
return 0;
if ( memo[index] != -1)
return memo[index];
int res = 0;
for( int i = index; i < nums.size(); i )
res = max( res, nums[i] tryRob(nums, i 2) );
memo[index] = res;
return res;
}
public:
int rob(vector<int>& nums) {
memo = vector<int>(nums.size(), -1);
return tryRob(nums, 0);
}
};
动态规划
代码语言:javascript复制class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
if ( n == 0)
return 0;
vector<int> memo(n, -1);
memo[n-1] = nums[n-1];
for( int i = n - 2; i >= 0; i-- ) {
for( int j = i; j < n; j ) {
memo[i] = max( memo[i], nums[j] (j 2 < n ? memo[j 2] : 0) );
}
}
return memo[0];
}
};
改变对状态的定义:
考虑偷取[0..x]范围里的房子(函数的定义)