动态规划——线性DP——状态转移
198 打家劫舍
- 使用dp[nums.size]记录有i间房时 对应的最大金额数;
- 初态 :
- 只有一间房,金额 nums[0];
- 转移条件
- 两间房:max(nums[0], nums[1]);
- 第i间房时:
- 若取当前房间的金额, 则总金额为dp[i-2]+nums[i-1];
- 若不取当前房间的金额,则总金额为dp[i-1];
- 比较上述两种情况,取其大者为dp[i];
- 即 代码表示
class Solution {
#define maxn 102
int dp[maxn]; //dp[i] means the max value of i numbers
public:
int rob(vector<int>& nums) {
dp[0] = nums[0];
for (int i = 1; i < nums.size();i++)
{
if (i == 1)
dp[i] = max(nums[0], nums[1]);
else
{
dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
}
}
return dp[nums.size() - 1];
}
};
213 打家劫舍2
- 与198的区别在于 第1间和最后一间相邻了,形成了环形
- 故若取第一间的金额,则不能取最后一间的金额
- 若不取第一间的金额,则可取最后一间的金额。
- 化环形为两条单直线
- 第1——n-1间为一部分考虑,求1——n-1间最大金额
- 第2——n间为一部分考虑,求2-n间最大金额
- 上述两者取最大者
class Solution {
#define maxn 112
int dp1[maxn],dp2[maxn];
public:
int rob(vector<int>& nums) {
int max_value=nums[0];
dp1[0] = nums[0];
for (int i = 1; i < nums.size()-1;i++)
{
if (i == 1)
dp1[i] = max(nums[0], nums[1]);
else
dp1[i] = max(dp1[i - 2] + nums[i], dp1[i - 1]);
};
// max_value=dp1[nums.size()-1];
if (nums.size() >=2)
max_value = dp1[nums.size() - 2];
else
max_value = dp1[nums.size() - 1];
if(nums.size()>=2)
{
max_value=dp1[nums.size()-2];
dp2[0] = nums[1];
for (int i = 1; i < nums.size()-1;i++)
{
if (i == 1)
dp2[i] = max(nums[1], nums[2]);
else
{
dp2[i] = max(dp2[i - 2] + nums[i+1], dp2[i - 1]);
};
};
max_value=max(max_value,dp2[nums.size() - 2]);
};
return max_value;
};
};
上述思路参考:
b站动态规划入门50题