1.爬楼梯
dp[i]为到达第i个阶梯的所有走法数量。
所求为dp[n]
dp数组没有必要一直存在,已知前两个即可。
int climbStairs(int n) {
//初始状态加上递推式
int num1=1,num2=2;
if(n<=2)
return n;
else
{
for(int i=2;i<n;++i)
{
int temp=num1+num2;
num1=num2;
num2=temp;
}
}
return num2;
}
2.买卖股票的最佳时机
dp[i]表示第i天卖出时的最大获利
所求为
只需一个dp缓存量即可,外加一个当前最低价格。
int maxProfit(vector<int>& prices) {
int min_price=INT_MAX;
int max_profit=0;
for(auto price:prices)
{
max_profit=max(max_profit,price-min_price);
min_price=min(min_price,price);
}
return max_profit;
}
3.最大子序和
dp[i]表示到i位置为最右侧的最大子序和
所求为max(dp[i])
int maxSubArray(vector<int>& nums) {
int max_sum=INT_MIN;
vector<int> dp(nums.size(),0);
int tmp_sum;
for(int i=0;i<nums.size();++i)
{
int _max_sum=0;
if(i==0)
{
tmp_sum=nums[i];
_max_sum=nums[i];
}
else
{
_max_sum=nums[i]+(tmp_sum>0?tmp_sum:0);
tmp_sum=_max_sum;
}
if(max_sum<_max_sum)
max_sum=_max_sum;
}
return max_sum;
}
4.打家劫舍
dp[i]表示从左往右打劫到第i家时的最大获利
dp[1]=nums[1],dp[2]=max(nums[1],nums[2])
所求为max(dp[n],dp[n-1])
int rob(vector<int>& nums) {
if(nums.size()==0)
return 0;
else if(nums.size()==1)
return nums.at(0);
//初始化
int a=nums[0];
int b=max(nums[0],nums[1]);
for(int i=2;i<nums.size();i++)
{
int temp=b;
b=max(a+nums[i],b);
a=temp;
}
return b;
}
本文深入探讨了四种经典的动态规划算法:爬楼梯、买卖股票的最佳时机、最大子序和及打家劫舍。通过详细解释每种算法的实现逻辑与核心代码,帮助读者理解动态规划在解决实际问题中的应用。
432

被折叠的 条评论
为什么被折叠?



