动态规划的解题思路是如何形成的
时间:2020-05-29
本文章向大家介绍动态规划的解题思路是如何形成的,主要包括动态规划的解题思路是如何形成的使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
机器人走路问题
一个机器人可以在1~N上行走,每一步可以向前或向后走,给定起点S > 1,终点 < N,每一次行走K步,机器人从S走到E一共有多少种方法。
暴力递归
暴力递归存在大量重复的递归过程。可以用空间换取时间,记录可能出现的重复解,之后不需要递归展开直接拿到之前算过的值。即,记忆化搜索。时间复杂度O(2^K)
1 public static int walkMethod(int N, int start, int end, int K){ 2 return process(N,start,end,K); 3 } 4 /** 5 * 6 * @param N 一共有N个位置 7 * @param cur 当前在哪个位置 8 * @param end 最终的目标位置 9 * @param restK 可以走几步 10 * @return 11 */ 12 private static int process(int N, int cur, int end, int restK) { 13 if(restK == 0){//不能继续走了 14 return cur == end? 1:0;//找到1种 或者 没找到 15 } 16 if(cur == 1){//只有一种走法 向右走 17 return process(N,2,end,restK-1); 18 } 19 if(cur == N){//只有一种走法 向左走 20 return process(N,N-1,end,restK-1); 21 } 22 //可以向左走 或者 向右走 23 return process(N,cur-1,end,restK-1) + 24 process(N,cur+1,end,restK-1); 25 }
记忆化搜索
时间复杂度O(K*N)
1 public static int walkMethod2(int N, int start, int end, int K) { 2 int dp[][] = new int[K + 1][N + 1]; 3 for (int i = 1; i <= K; i++) { 4 for (int j = 0; j <= N; j++) { 5 dp[i][j] = -1; 6 } 7 } 8 return process2(N, start, end, K, dp); 9 } 10 11 private static int process2(int N, int cur, int end, int restK, int[][] dp) { 12 if (dp[restK][cur] != -1) { 13 return dp[restK][cur];//之前计算过 直接return 14 } 15 if (restK == 0) { 16 dp[restK][cur] = cur == end ? 1 : 0; 17 return dp[restK][cur]; 18 } 19 if (cur == 1) { 20 dp[restK][cur] = process2(N, cur + 1, end, restK - 1, dp); 21 }else if (cur == N) { 22 dp[restK][cur] = process2(N, cur - 1, end, restK - 1, dp); 23 }else{ 24 dp[restK][cur] = process2(N, cur - 1, end, restK - 1, dp) + process2(N, cur + 1, end, restK - 1, dp); 25 } 26 return dp[restK][cur]; 27 }
严格表结构
表的含义是:restK步走到cur有f(restK, cur)种方法
从开始 2 走到 终点 4 【f(0,4) = 1 f(0,else) = 0】走4步有多少种方法
dp(restK, cur) = dp(restK-1, cur-1) 【cur == N】
dp(restK, cur) = dp(restK+1, cur-1) 【cur == 1】
dp(restK, cur) = dp(restK-1, cur-1) + dp(restK+1, cur-1) 【1<cur<N】
return dp(K, start)
原文地址:https://www.cnblogs.com/xdcat/p/12988691.html
- CSS3伪类和伪元素的特性和区别
- Kafka剖析系列之Benchmark
- 初探React与D3的结合-或许是visualization的新突破?
- Redis 在Centos Linux 上的启动脚本
- 理解JavaScript的临时包装对象
- JavaScript实现私有属性
- 使用LRU算法缓存图片,android 3.0
- 深入理解JavaScript原型:prototype,__proto__和constructor
- Comparable 与 Comparator 浅析
- 必应首页平铺背景图片的实现方案
- 我们是如何优化HAProxy以让其支持200万个并发SSL连接的?
- 【译】《Understanding ECMAScript6》- 第八章-Module
- 【译】《Understanding ECMAScript6》- 第七章-Promise
- 自定义gradview
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- java线程池(四):ForkJoinPool的使用及基本原理
- 算法书中算法
- Robo3T 与 NaviCat 的安装
- 牛客网2017年校招真题-1
- 实例分割新思路之SOLO v1&v2深度解析
- 牛客网剑指offer-3
- java8新特性总结备忘
- 商业数据分析从入门到入职(6)Python程序结构和函数
- 数据科学家极力推荐核心计算工具-Numpy的前世今生(下)
- Android 重构 | 持续优化统一管理 Gradle
- 快速学习-XXL-JOB调度中心/执行器 RESTful API
- 快速学习-XXL-JOB快速入门
- binlog2sql,你该知道的数据恢复工具
- java反射总结
- 玩转dnmp之port篇