当前位置: 首页 > news >正文

乐东黎族自治县网站建设_网站建设公司_MySQL_seo优化

室内设计和平面设计哪个比较吃香,东营网站建设课程定位优化,做软件赚钱吗,建设银行不会自动弹出网站目录 一、动态规划理论基础 1.动态规划的解题步骤 2.动态规划应该如何debug 二、#xff08;leetcode 509#xff09;斐波那契数 1.递归解法 2.动态规划 1#xff09;确定dp数组以及下标的含义 2#xff09;确定递推公式 3#xff09;dp数组如何初始化 4#x… 目录 一、动态规划理论基础 1.动态规划的解题步骤 2.动态规划应该如何debug 二、leetcode 509斐波那契数 1.递归解法 2.动态规划 1确定dp数组以及下标的含义 2确定递推公式 3dp数组如何初始化 4确定遍历顺序 5举例推导dp数组 三、leetcode 70 爬楼梯 四、leetcode 746使用最小花费爬楼梯 1.新题目描述 2.原题目描述 一、动态规划理论基础 动态规划英文Dynamic Programming简称DP动态规划中每一个状态一定是由上一个状态推导出来的这一点就区分于贪心贪心没有状态推导而是从局部直接选最优的 1.动态规划的解题步骤 确定dp数组dp table以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组 为什么要先确定递推公式然后在考虑初始化呢因为一些情况是递推公式决定了dp数组要如何初始化 2.动态规划应该如何debug 找问题的最好方式就是把dp数组打印出来看看究竟是不是按照自己思路推导的 做动规的题目写代码之前一定要把状态转移在dp数组的上具体情况模拟一遍心中有数确定最后推出的是想要的结果。 然后再写代码如果代码没通过就打印dp数组看看是不是和自己预先推导的哪里不一样。 如果打印出来和自己预先模拟推导是一样的那么就是自己的递归公式、初始化或者遍历顺序有问题了。 如果和自己预先模拟推导的不一样那么就是代码实现细节有问题。 可以自己先思考这三个问题 这道题目我举例推导状态转移公式了么我打印dp数组的日志了么打印出来了dp数组和我想的一样么 如果这灵魂三问自己都做到了基本上这道题目也就解决了或者更清晰的知道自己究竟是哪一点不明白是状态转移不明白还是实现代码不知道该怎么写还是不理解遍历dp数组的顺序。 注意这里不是说不让大家问问题哈 而是说问问题之前要有自己的思考问题要问到点子上 二、leetcode 509斐波那契数 力扣题目链接 1.递归解法 class Solution { public:int fib(int n) {if(n2) return n;else return fib(n-1)fib(n-2);} }; 时间复杂度O(2^n)空间复杂度O(n)算上了编程语言中实现递归的系统栈所占空间 2.动态规划 动规五部曲这里要用一个一维dp数组来保存递归的结果 1确定dp数组以及下标的含义 dp[i]的定义为第i个数的斐波那契数值是dp[i] 2确定递推公式 题目已经把递推公式直接给我们了状态转移方程 dp[i] dp[i - 1] dp[i - 2] 3dp数组如何初始化 题目中把如何初始化也直接给了 dp[0] 0; dp[1] 1;4确定遍历顺序 从递归公式dp[i] dp[i - 1] dp[i - 2];中可以看出dp[i]是依赖 dp[i - 1] 和 dp[i - 2]那么遍历的顺序一定是从前到后遍历的 5举例推导dp数组 按照这个递推公式dp[i] dp[i - 1] dp[i - 2]我们来推导一下当N为10的时候dp数组应该是如下的数列 0 1 1 2 3 5 8 13 21 34 55 如果代码写出来发现结果不对就把dp数组打印出来看看和我们推导的数列是不是一致的。 class Solution { public:int fib(int N) {if (N 1) return N;vectorint dp(N 1);dp[0] 0;dp[1] 1;for (int i 2; i N; i) {dp[i] dp[i - 1] dp[i - 2];}return dp[N];} }; 时间复杂度O(n)空间复杂度O(n) 当然可以发现只需要维护两个数值就可以了不需要记录整个序列。 代码如下 class Solution { public:int fib(int N) {if (N 1) return N;int dp[2];dp[0] 0;dp[1] 1;for (int i 2; i N; i) {int sum dp[0] dp[1];dp[0] dp[1];dp[1] sum;}return dp[1];} };时间复杂度O(n)空间复杂度O(1) 三、leetcode 70 爬楼梯 力扣题目链接 暗戳戳说感觉这道题跟上面一道题一样啊就是有了实际背景 动规五部曲 定义一个一维数组来记录不同楼层的状态 1确定dp数组以及下标的含义 dp[i] 爬到第i层楼梯有dp[i]种方法 2确定递推公式 从dp[i]的定义可以看出dp[i] 可以有两个方向推出来。 首先是dp[i - 1]上i-1层楼梯有dp[i - 1]种方法那么再一步跳一个台阶不就是dp[i]了么。 还有就是dp[i - 2]上i-2层楼梯有dp[i - 2]种方法那么再一步跳两个台阶不就是dp[i]了么。 那么dp[i]就是 dp[i - 1]与dp[i - 2]之和 所以dp[i] dp[i - 1] dp[i - 2] 。 3dp数组如何初始化 不考虑dp[0]如何初始化只初始化dp[1] 1dp[2] 2然后从i 3开始递推这样才符合dp[i]的定义。dp[0]不管怎么定义都很牵强那就不定义了就是这么任性嘻嘻 4确定遍历顺序 从递推公式dp[i] dp[i - 1] dp[i - 2];中可以看出遍历顺序一定是从前向后遍历的 5举例推导dp数组 举例当n为5的时候dp tabledp数组应该是这样的 以上五部分析完之后C代码如下 // 版本一 class Solution { public:int climbStairs(int n) {if (n 1) return n; // 因为下面直接对dp[2]操作了防止空指针vectorint dp(n 1);dp[1] 1;dp[2] 2;for (int i 3; i n; i) { // 注意i是从3开始的dp[i] dp[i - 1] dp[i - 2];}return dp[n];} };时间复杂度O(n)空间复杂度O(n) 当然依然也可以优化一下空间复杂度代码如下 // 版本二 class Solution { public:int climbStairs(int n) {if (n 1) return n;int dp[3];dp[1] 1;dp[2] 2;for (int i 3; i n; i) {int sum dp[1] dp[2];dp[1] dp[2];dp[2] sum;}return dp[2];} }; 时间复杂度O(n)空间复杂度O(1) 后面的很多动规的题目其实都是当前状态依赖前两个或者前三个状态都可以做空间上的优化但面试中能写出版本一就够了哈清晰明了如果面试官要求进一步优化空间的话再去优化。因为版本一才能体现出动规的思想精髓递推的状态变化。 四、leetcode 746使用最小花费爬楼梯 力扣题目链接 1.新题目描述 1确定dp数组以及下标的含义 使用动态规划就要有一个数组来记录状态本题只需要一个一维数组dp[i]就可以了。 dp[i]的定义到达第i台阶所花费的最少体力为dp[i]。 2确定递推公式 可以有两个途径得到dp[i]一个是dp[i-1] 一个是dp[i-2]。 dp[i - 1] 跳到 dp[i] 需要花费 dp[i - 1] cost[i - 1]。 dp[i - 2] 跳到 dp[i] 需要花费 dp[i - 2] cost[i - 2]。 那么究竟是选从dp[i - 1]跳还是从dp[i - 2]跳呢 一定是选最小的所以dp[i] min(dp[i - 1] cost[i - 1], dp[i - 2] cost[i - 2]); 3dp数组如何初始化 看一下递归公式dp[i]由dp[i - 1]dp[i - 2]推出既然初始化所有的dp[i]是不可能的那么只初始化dp[0]和dp[1]就够了其他的最终都是dp[0]dp[1]推出。 那么 dp[0] 应该是多少呢 根据dp数组的定义到达第0台阶所花费的最小体力为dp[0]那么有同学可能想那dp[0] 应该是 cost[0]例如 cost [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] 的话dp[0] 就是 cost[0] 应该是1。 这里就要说明本题力扣为什么改题意而且修改题意之后就清晰很多的原因了。 新题目描述中明确说了 “你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。” 也就是说 到达 第 0 个台阶是不花费的但从 第0 个台阶 往上跳的话需要花费 cost[0]。 所以初始化 dp[0] 0dp[1] 0; 4确定遍历顺序 最后一步递归公式有了初始化有了如何遍历呢 本题的遍历顺序其实比较简单简单到很多同学都忽略了思考这一步直接就把代码写出来了。 因为是模拟台阶而且dp[i]由dp[i-1]dp[i-2]推出所以是从前到后遍历cost数组就可以了。 但是稍稍有点难度的动态规划其遍历顺序并不容易确定下来。 例如01背包都知道两个for循环一个for遍历物品嵌套一个for遍历背包容量那么为什么不是一个for遍历背包容量嵌套一个for遍历物品呢 以及在使用一维dp数组的时候遍历背包容量为什么要倒序呢 这些都与遍历顺序息息相关。 5举例推导dp数组 拿示例2cost [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] 来模拟一下dp数组的状态变化如下 以上分析完毕整体C代码如下 class Solution { public:int minCostClimbingStairs(vectorint cost) {vectorint dp(cost.size() 1);dp[0] 0; // 默认第一步都是不花费体力的dp[1] 0;for (int i 2; i cost.size(); i) {dp[i] min(dp[i - 1] cost[i - 1], dp[i - 2] cost[i - 2]);}return dp[cost.size()];} };时间复杂度O(n)空间复杂度O(n) 还可以优化空间复杂度因为dp[i]就是由前两位推出来的那么也不用dp数组了C代码如下 // 版本二 class Solution { public:int minCostClimbingStairs(vectorint cost) {int dp0 0;int dp1 0;for (int i 2; i cost.size(); i) {int dpi min(dp1 cost[i - 1], dp0 cost[i - 2]);dp0 dp1; // 记录一下前两位dp1 dpi;}return dp1;} };时间复杂度O(n)空间复杂度O(1) 2.原题目描述 旧力扣描述如果按照第一步是花费的最后一步不花费那么代码是这么写的 // 版本一 class Solution { public:int minCostClimbingStairs(vectorint cost) {vectorint dp(cost.size());dp[0] cost[0]; // 第一步有花费dp[1] cost[1];for (int i 2; i cost.size(); i) {dp[i] min(dp[i - 1], dp[i - 2]) cost[i];}// 注意最后一步可以理解为不用花费所以取倒数第一步第二步的最少值return min(dp[cost.size() - 1], dp[cost.size() - 2]);} };
http://www.ihoyoo.com/news/69304.html

相关文章:

  • 网站建设中++模板辽宁建设工程信息网中标通知书
  • 深圳罗湖企业网站建设网站建设推广服务商
  • 专业做书画推广的网站个人网站源码模板
  • 做网站比特币钱包西部数码网站管理助手 2008
  • 企业网站开发需求分析网络设计采用的方法和原则
  • 网站推荐几个长沙新闻
  • 科技微网站wordpress+培训模板下载
  • 查询网站内页关键词排名天津网站建设制作
  • 百度网站制作网络营销方式介绍
  • 排名好的网站关键词优化企业网上快速学做网站
  • 网站建设设计合同书旅游兼职网站建设
  • 有域名之后怎样进行网站建设厦门酒店网站建设
  • 徐州网站制作哪家好承德网站建设公司
  • 做外贸网站哪家效果好用织梦做的网站好用吗
  • asp网站用什么数据库给网站做认证
  • 松江叶榭网站建设江苏建设工程网站
  • 网站建设国内外研究进展哪种网站名称容易通过备案审核
  • 最便宜的视频网站建设界面设计图片素材
  • 网站建设 保障接单 计划湖南网站设计方案
  • 网站美工用什么软件无法分享到微信wordpress
  • 网站开发培训流程制作网站的专业公司哪家好
  • 去哪儿网站排名怎么做网站建设后台管理怎么管理
  • 地产公司网站建设计划书汽车网站案例网页设计
  • 中文html网站模板下载wordpress 图片文件夹
  • 如何查询网站的注册信息做微博网站好不好
  • 建立网站费用大概需要多少钱wordpress 点赞打赏
  • 查询网站最新域名seo咨询推广找推推蛙
  • 网站开发个人所得税网站建设推广优化岗位说明书
  • 擅自给公司做网站有什么责任dedecms安装教程
  • 沧州1 1 网站建设一个域名访问不同的网站