连续子数组的最大和
动规五部曲:
确定dp数组及其下标的含义
dp[i]表示以nums[i]结尾的最大连续子数组和为dp[i]
确定递推关系式
dp[i]有两种可能,一个是此时的nums[i]仍在连续数组范围内,还有一种为从它开始为连续数组的起点
dp[i]=max(nums[i],dp[i-1]+nums[i])
dp数组的初始化
dp[0]=nums[0]
确定遍历顺序
从前往后遍历
举例验证dp数组
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.empty()) return 0;
int length=nums.size();
vector<int> dp(length);
dp[0]=nums[0];
for(int i=1;i<length;i++)
{
dp[i]=max(dp[i-1]+nums[i],nums[i]);
}
int result=INT_MIN;
for(int i=0;i<length;i++)
{
result=max(result,dp[i]);
}
return result;
}
};
礼物的最大价值
类似于路径的最大和
动规五部曲:
确定dp数组及其下标的含义
dp[i][j]表示在grid数组中i,j位置时最大的礼物价值
确定递推关系式
dp[i][j]=grid[i][j]+max(dp[i-1][j],dp[i][j-1])
dp数组的初始化
第一行和第一列特殊,直接加,只有一种路径
确定遍历顺序
从前往后
dp数组举例验证
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int m=grid.size(),n=grid[0].size();
if(m==0) return 0;
vector<vector<int>> dp(m,vector<int> (n,0));
dp[0][0]=grid[0][0];
for(int i=1;i<m;i++)
{
dp[i][0]=grid[i][0]+dp[i-1][0];
}
for(int j=1;j<n;j++)
{
dp[0][j]=grid[0][j]+dp[0][j-1];
}
for(int i=1;i<m;i++)
{
for(int j=1;j<n;j++)
{
dp[i][j]=grid[i][j]+max(dp[i-1][j],dp[i][j-1]);
}
}
return dp[m-1][n-1];
}
};