力扣198.打家劫舍|动态规划解法中的特殊边界处理
题意解析:
在排列成直线的房屋群中,每个房屋藏有价值不同的财物。小偷不能连续抢劫相邻的两间房屋,否则会触发警报。我们需要设计一套抢劫策略,使得在不触发警报的前提下,能够获取的最大财物总和。这个问题本质上是在不连续区间内寻找价值最大化的数学组合问题。
思路解析:
采用动态规划+特殊边界处理策略:
1.极端情况处理:
房屋数量≤3时直接比较所有可能的组合结果
当只有3间房时,最大收益为“首尾之和”或“中间值”的较大者
2.DP数组构建:
dp[i]存储前i间房的理论最大收益
初始化前三个状态:dp[0]存首房价值,dp[1]取前两房较大值,dp[2]对比三种可能性
3.递推策略创新:
从第4间房开始,递推式dp[i] = max(dp[i-2]+nums[i], dp[i-3]+nums[i-1])
不仅考虑前两间的状态,还引入前三间状态的对比,有效避免局部最优陷阱
4.最大值维护:
每次计算新的dp[i]后更新全局最大值maxdp
最终返回遍历过程中出现的最大收益值57
代码注释:
class Solution { public: int rob(vector<int>& nums) { // 处理房屋数量少的特殊情况 if(nums.size()==1) return nums[0]; // 仅一间房直接返回 if(nums.size()==2) return max(nums[0],nums[1]);// 两间房取较大值 if(nums.size()==3) // 三间房特殊处理 return max(nums[0]+nums[2],nums[1]); // 比较首尾之和与中间值 int dp[100]; // DP数组预留足够空间 dp[0]=nums[0]; // 首间房必选 dp[1]=max(nums[0],nums[1]); // 前两间取较大者 dp[2]=max(nums[0]+nums[2],nums[1]); // 前三间最优解计算 int maxdp=dp[2]; // 初始化当前最大值 // 动态规划递推过程 for(int i=3;i<nums.size();i++) { // 核心状态转移方程:比较两种跨步方案 dp[i]=max(dp[i-2]+nums[i], // 方案一:间隔两间抢当前房 dp[i-3]+nums[i-1]);// 方案二:间隔三间抢前一房 maxdp=max(dp[i],maxdp); // 动态维护全局最大值 } return maxdp; // 返回计算的最高收益 } };
原创内容 转载请注明出处