动态规划解题步骤:
1.确定状态表示:dpi是什么
2.确定状态转移方程:dpi等于什么
4.确定填表顺序:根据状态转移方程即可确定填表顺序
5.确定返回值
题目链接: 面试题 17.16. 按摩师 - 力扣(LeetCode)

题解1(斐波那契数列模型):
1.状态表示: dpi表示接受numsi预约的最优预约
2.状态转移方程:dpi=numsi+max(dpi-2,dpi-3) 由于接受了numsi的预约,所以只能接受numsi-2或者numsi-3的预约
3.初始化:dp0=nums0、dp1=nums1、dp2=nums0+nums2
4.填表顺序:一维数组,从左向右填写
5.返回值:max(dpn-1,dpn-2) 最优预约只能是接受最后一天或者倒数第二天预约
cpp
class Solution {
public:
int massage(vector<int>& nums) {
size_t n=nums.size();
//处理边界条件
if(n==0)
return 0;
if(n==1)
return nums[0];
if(n==2)
return max(nums[0],nums[1]);
if(n==3)
return max(nums[0]+nums[2],nums[1]);
//dp[i]表示最后一个预约是nums[i]的最优预约
//创建dp表
vector<int> dp(n);
//初始化
dp[0]=nums[0];
dp[1]=nums[1];
dp[2]=nums[0]+nums[2];
//填表
for(int i=3;i<n;++i)
{
dp[i]=nums[i]+max(dp[i-2],dp[i-3]);
}
//返回值
return max(dp[n-1],dp[n-2]);
}
};
题解2(简单多状态dp问题):
1.状态表示:有两个dp表,分别为fi和gi,分别表示接受numsi预约和不接受numsi预约的最优预约
2.状态转移方程:fi=numsi+gi-1 gi=max(fi-1,gi-1) 接受numsi的预约,最佳预约就是再加上不接受前一个预约的最佳预约;不接受numsi的预约,最佳预约就是取接受或者不接受前一个预约的最大值
3.初始化:f0=nums0 g0=0
4.填表顺序:一维数组,从左向右填写
5.返回值:max(fn-1,gn-1)
cpp
class Solution {
public:
int massage(vector<int>& nums) {
size_t n=nums.size();
//处理边界条件
if(n==0)
return 0;
//创建dp表
vector<int> f(n);
auto g=f;
//初始化
f[0]=nums[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]);
}
return max(f[n-1],g[n-1]);
}
};