动态规划

前言:最近开始学习数据结构与算法,顺便刷leetcode,无意间发现了一个我觉得讲解的比较好的网页,并且会那leetcode里面的题目当做例题,如有需要,奉上网址:五分钟学算法
一、基本概念
1.什么是动态规划
一句话概括:记住你之前做过的事情—记住你之前的答案。
2.动态规划问题的四个步骤
①问题拆解,找到问题之间的具体联系。
②状态定义,拆解出来的小问题之间的联系与什么状态相关联。
③递推方程推导。
④实现。
二、初级题目实战
1.爬楼梯(Leetcode第70号问题)
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
在这里插入图片描述
在这里插入图片描述
问题拆解:
我们到达第 n 个楼梯可以从第 n - 1 个楼梯和第 n - 2 个楼梯到达,因此第 n 个问题可以拆解成第 n - 1 个问题和第 n - 2 个问题,第 n - 1 个问题和第 n - 2 个问题又可以继续往下拆,直到第 0 个问题,也就是第 0 个楼梯 (起点)

状态定义

“问题拆解” 中已经提到了,第 n 个楼梯会和第 n - 1 和第 n - 2 个楼梯有关联,那么具体的联系是什么呢?你可以这样思考,第 n - 1 个问题里面的答案其实是从起点到达第 n - 1 个楼梯的路径总数,n - 2 同理,从第 n - 1 个楼梯可以到达第 n 个楼梯,从第 n - 2 也可以,并且路径没有重复,因此我们可以把第 i 个状态定义为 “从起点到达第 i 个楼梯的路径总数”,状态之间的联系其实是相加的关系。

递推方程

“状态定义” 中我们已经定义好了状态,也知道第 i 个状态可以由第 i - 1 个状态和第 i - 2 个状态通过相加得到,因此递推方程就出来了 dp[i] = dp[i - 1] + dp[i - 2]

实现

你其实可以从递推方程看到,我们需要有一个初始值来方便我们计算,起始位置不需要移动 dp[0] = 0,第 1 层楼梯只能从起始位置到达,因此 dp[1] = 1,第 2 层楼梯可以从起始位置和第 1 层楼梯到达,因此 dp[2] = 2,有了这些初始值,后面就可以通过这几个初始值进行递推得到。

class Solution {
public:
    int climbStairs(int n) {
        if(n<=3)
            return n;
        int dp[n+1];
        dp[1]=1;
        dp[2]=2;
        for(int i=3;i<=n;i++)
        {
            dp[i]=dp[i-1]+dp[i-2];
        }

        return dp[n];
    }
};

2.三角形最小路径和(LeetCode 第 120 号问题)
步骤同上一题
本体递推方程:dp[i][j] = Math.min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle[i][j]

class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        if(triangle.empty())
            return 0;
        int L=triangle.size();
        for(int i=1;i<L;++i)
            for(int j=0;j<triangle[i].size();++j)
            {
                int right=(j<triangle[i-1].size())? triangle[i-1][j]:INT_MAX;
                int left=(j>=1&&j-1<triangle[i-1].size())? triangle[i-1][j-1]:INT_MAX;
                triangle[i][j]+=(right<left)? right:left;
            }
        int res=INT_MAX;
        for(int j=0;j<triangle[L-1].size();++j)
            res=(triangle[L-1][j]<res)? triangle[L-1][j]:res;

        return res;
    }

3.最大子序和(LeetCode 第 53 号问题)
本体递推方程:dp[i] = max(dp[i - 1], 0) + array[i]

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int amax=nums[0];
        int bmax=nums[0];
        int length=nums.size();
        for(int i=1;i<length;i++)
        {
            if(bmax>0)
                bmax+=nums[i];
            else
                bmax=nums[i];
            amax=max(amax,bmax);
        }
        return amax;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值