动态规划解题步骤:
1.确定状态表示:dp[i]是什么
2.确定状态转移方程:dp[i]等于什么
3.初始化:确保状态转移方程不越界
4.确定填表顺序:根据状态转移方程即可确定填表顺序
5.确定返回值
题目链接:413. 等差数列划分 - 力扣(LeetCode)
题解:
1.状态表示:dp[i]表示以nums[i]结尾且是等差数列子数组的个数
2.状态转移方程:
求状态转移方程之前,先理解:如果[a,b,c,d,e]是等差数列,[d,e,f]也是等差数列,那么[a,b,c,d,e,f]是等差数列。所以dp[i]可以根据dp[i-1]推出,如果nums[i]和nums[i-1]、nums[i-2]成等差数列,那么dp[i-1]所指的等差数列再加上nums[i]也一定是一个等差数列;同理,如果nums[i]和nums[i-1]、nums[i-2]不成等差数列,那么以nums[i]结尾的一定没有等差数列。
因此状态转移方程:if(nums[i]-nums[i-1]==nums[i-1]-nums[i-2]) dp[i]=dp[i-1]+1;
else dp[i]=0;
3.初始化:dp[0]=dp[1]=0 等差数列至少有三个数
4.填表顺序:从左向右依次填写
5.返回值:返回dp表中的最大值
class Solution {
public:
int numberOfArithmeticSlices(vector<int>& nums) {
//dp[i]表示以nums[i]结尾是等差数列子数组的个数
//nums[i]-nums[i-1]=nums[i-1]-nums[i-2] dp[i]=dp[i-1]+1
size_t n=nums.size();
//处理边界条件
if(n==1||n==2) return 0;
//创建dp表
vector<int> dp(n);
//初始化
dp[0]=dp[1]=0;
//填表
for(int i=2;i<n;++i)
{
if(nums[i]-nums[i-1]==nums[i-1]-nums[i-2])
dp[i]=dp[i-1]+1;
else
dp[i]=0;
}
//返回值
int ans=0;
for(auto e:dp) ans+=e;
return ans;
}
};