博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
动态规划的套路----左神
阅读量:4180 次
发布时间:2019-05-26

本文共 1670 字,大约阅读时间需要 5 分钟。

一、动态规划

首先动态规划不是一种数据结构,而是一种优化,它是一种用空间换时间的套路,它是递归的进阶版本。

二、动态规划的套路

使用动态规划套路的一个原则是能想出递归的解法。由递归来改成动态规划。

在这里插入图片描述

我们以这套例题来解释动态规划的套路

第一步: 写出递归的“试”法,看看如何尝试可以解决问题。

num:表示前几步已选择的值的和, 变量

id:在下标为 0 — id-1中的数中进行选择,变量
target:程序输入的目标和,常量
arr[]: 程序输入的数组,常量

//{3,1,4,2,7}	public static boolean isSum(int[] nums, int i, int sum, int target){
if(i == nums.length-1) return sum == target; return isSum(nums, i+1, sum, target)||isSum(nums, i+1, sum+nums[i], target);//这个方法会遍历所有的子集合 }

第二步: 判断是否是无后效性问题, 什么叫后效性问题?上面这个例子,现在有一个进入isEquals(num:7,id:3)的方法,那么这个方法计算的结果,和它是通过何种方式进入的无关。比方说通过选择3和4 , 或者选择7, 都能进入这个状态,但是一旦进入这个状态那么得到的值和前几步的选择无关。

无后效性中的变量, id num 就作为动态规划dp数组的变量。

第三步: 确定目标状态,id = 0 , num = 0 ,是目标状态。(这里其实还比较不好理解,这是根据我们递归程序的入口定义的)

第四步: 求出终止状态和基础条件。这里也要参照我们写的递归方法

当id == arr.length时,num == target(从前n个中选,选出来的总和 == target) ,这个状态是true; 当id == arr.length,num != target,那么这些状态是false。

在这里插入图片描述

最后一步: 确定普遍位置由哪些精确位置得到。

递归函数中写了,DP[id][num] = DP[id+1][num] || DP[id+1][num + arr[id]],因此这就是状态转移方程。现在进行填表即可。

从n-1行开始,DP[id][num] 需要查看DP[id+1][num] 和 DP[i+1][num + arr[id]] 这两个位置的值。 然后一步步把表填满,完成!

DP的代码不过就是把刷表的过程模拟了一遍而已。

public static boolean isSumByDP(int target,int[] arrs){
int sum = 0; for(int i = 0; i < arrs.length; i++) {
sum += arrs[i]; } if(target > sum)return false;//所有值加起来都没有目标值大,直接返回false boolean[][] dp = new boolean[arrs.length+1][sum+1]; for (int j = 0; j <= sum; j++) {
//先将最后一行已经知道结果的填充进去 dp[arrs.length][j] = j==target; } for(int i = arrs.length - 1; i >= 0; i--) for(int j = 0; j <= sum; j++) {
if(j + arrs[i] <= sum){
//不超出部分,j+arrs[i]表示当前叠加值加上该位置值 dp[i][j] = dp[i+1][j] || dp[i+1][j+arrs[i]];//选中和不选中方案 } } return dp[0][0]; }

转载地址:http://vxrai.baihongyu.com/

你可能感兴趣的文章
vue1.0与2.0区别之生命周期
查看>>
vue2.0之非父子组件通信
查看>>
如何建立svn版本库并运行它
查看>>
如何合并svn分支到主干上
查看>>
libusb源码学习:list_entry
查看>>
libusb源码学习:几个函数加载的宏(windows)
查看>>
MCU_如何通过硬件VID 查找生产厂家
查看>>
NCNN部署例程 mxnet-gluoncv之simple_pose
查看>>
Ubuntu18.04查看显卡信息并安装NVDIA显卡驱动driver + Cuda + Cudnn
查看>>
电子元件二极管封装SMA,SMB,SMC的区别
查看>>
利用FFmpeg玩转Android视频录制与压缩(二)
查看>>
eclipse下生成Java类图和时序图,生成UML图
查看>>
M文件程序设计(matlab)
查看>>
matlab基础知识
查看>>
程序员的职业素养
查看>>
一道面试题深入了解java底层
查看>>
java下载附件
查看>>
cron表达式每个月最后一天
查看>>
Oracle中Like与Instr模糊查询性能大比拼
查看>>
Spring Boot入门===Hello World
查看>>