动态规划解题步骤:
1.确定状态表示:dp[i]是什么
2.确定状态转移方程:dp[i]等于什么
3.初始化:确保状态转移方程不越界
4.确定填表顺序:根据状态转移方程即可确定填表顺序
5.确定返回值
题目链接:213. 打家劫舍 II - 力扣(LeetCode)
题解:
本题实际上就是分两种情况,每种情况在不同的区间中进行打家劫舍1算法
1.状态表示:f[i]表示最后一间房屋为nums[i]并且偷的最高金额;g[i]表示最后一间房屋为nums[i]并且偷的最高金额
2.状态转移方程:f[i]=nums[i]+g[i-1] g[i]=max(f[i-1],g[i-1])
3.初始化:这要分情况初始化,根据是否偷第一间房子分为两种情况。偷第一间房子则f[0]=nums[0] g[0]=0;不偷第一间房子则f[0]=g[0]=0
4.填表顺序:从左向右填写,两个表一起填
5.返回值:取两种情况的最大金额
class Solution {
public:
int rob(vector<int>& nums) {
//f[i]表示最后一间房屋为nums[i]并且偷的最高金额
//g[i]表示最后一间房屋为nums[i]并且偷的最高金额
//f[i]=nums[i]+g[i-1];
//g[i]=max(f[i-1],g[i-1])
size_t n=nums.size();
//处理边界条件
if(n==1)
return nums[0];
if(n==2)
return max(nums[0],nums[1]);
//创建dp表
vector<int> f(n);
auto g=f;
//分情况
int ret1=0;
int ret2=0;
//情况1:偷第一间屋子
//初始化
f[0]=nums[0];
g[0]=0;
for(int i=2;i<n-1;++i)
{
f[i]=nums[i]+g[i-1];
g[i]=max(f[i-1],g[i-1]);
}
ret1=nums[0]+max(f[n-2],g[n-2]);
//情况2:不偷第一间屋子
//初始化
f[0]=g[0]=0;
for(int i=1;i<n;++i)
{
f[i]=nums[i]+g[i-1];
g[i]=max(f[i-1],g[i-1]);
}
ret2=max(f[n-1],g[n-1]);
return max(ret1,ret2);
}
};