初识动态规划(一)简单入门动态规划与上手操作
dp动态规划
一、认识动态规划
前言:近期我在慢慢刷动态规划的题,虽然还是入门阶段,但还是准备记录我动态规划前期是如何刷题过程
先根据一个例题来引入动态规划——换零钱
提出问题:要求使用1,5,11的钞票面额进行换总金额为w的最小张数
分析问题:在兑换的最终情况下(即换一最后一张面额的情况),要么是面额为1,要么5,要么11,所以
我们可以得出:(f(w)表示换w金额需要的最少张数)
- f(w) = f(w - 1) + 1; //该式子表示的是如果要得出f(w),就用前面已得出的f(w - 1) 加上一张面额为1的钞票即可
- f(w) = f(w - 5) + 1;//该式子表示的是如果要得出f(w),就用前面已得出的f(w - 5) 加上一张面额为5的钞票即可
- f(w) = f(w - 11) + 1;
故我们可知,若是求最少换零钱的张数就是
f(w - 1) & f(w - 5) & f(w - 11)
三个中最小的那一个
3. 给出具体例子
那么,假如w=15的时候,同样,钞票面额分别为1,5,11,我们该取那种钞票呢?当然是各种方案中,cost值最低的那一个!- 取1:cost = f(14) + 1 = 4 + 1 = 5;- 取5:cost = f(10) + 1 = 2 + 1 = 3;- 取11:cost = f(4) + 1 = 4 + 1 = 5;再次深度解释一下:其中第二个取5的式子:f(10) = f(10 - 5) + 1 = 1 + 1; 即子问题的解;第三个取11的式子:f(4) = f(4 - 1) + 1 = 4;
得出结论
大致我们可以得出,我们所求的就是前面 当前最优值 = 前面最优值 + 1
我们将求解f(w)就可以理解为求解多个子问题来达到求解f(w)
这就是dp --> 动态规划
解决问题的特点
能将大问题拆成几个小问题,且满足无后效性(即不管前面的过程,只需要得出前面的子最优解解即可)
最优子结构性质,能够由子问题推导出结果
详细来说:
- 求最大最小值
- 从左上角走到右下角路径的最大数字和
- 最长上升子序列
- 最长等差序列
- 最少换钱张数
- 计数
- 有多少种方式走到右下角
- 有多少种方法选出k个数使得和是sum
- 爬楼梯
- 判断
- 是否存在先手赢,取石子游戏
- 求最大最小值
解题一般步骤
- 判断是否是最优问题,并存在子问题
- 确定dp数组用一维或者更多,并且表示什么意思
- 比如dp[i][j】,表示为从i下标到j下标长度的回文子串个数
- 推导出dp状态方程,和判断条件
- 确定好dp初始数组长度,和是否设立初始值
- 选用合适的循环条件达到自己的目的
二、下面进行具体刷动规的题型
斐波那契数
零钱兑换
最长递增子序列
爬楼梯
斐波那契数
斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n ,请计算 F(n) 。示例 1:
输入:n = 2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1
示例 2:输入:n = 3
输出:2
解释:F(3) = F(2) + F(1) = 1 + 1 = 2
示例 3:输入:n = 4
输出:3
解释:F(4) = F(3) + F(2) = 2 + 1 = 3来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/fibonacci-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。class Solution {public int fib(int n) {//动态规划 dp[i] 表示的是第i个数表示的值if (n == 0) return 0; //处理特殊情况int []dp = new int[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]; //得到最终结果} }
零钱兑换
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。
你可以认为每种硬币的数量是无限的。
示例 1:
输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1
示例 2:输入:coins = [2], amount = 3
输出:-1
示例 3:输入:coins = [1], amount = 0
输出:0来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/coin-change
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。class Solution {public int coinChange(int[] coins, int amount) {//动态规划int[] dp = new int[amount+1];Arrays.fill(dp, amount+1);//base casedp[0] = 0;// 外层的for循环在遍历时实现遍历所有状态的所有取值for(int i = 0; i < dp.length; i++){// 内层for循环求在所有选择中的最小值for(int coin : coins){//子问题无解,跳过if(i - coin < 0){continue;}//状态转移dp[i] = Math.min(dp[i],1+dp[i-coin]);}}//查看金额能不能算出来return (dp[amount] == amount+1 ? -1 : dp[amount]);//暴力递归——超时// if (amount == 0){// return 0;// }// if (amount < 0){// return -1;// }// int min = Integer.MAX_VALUE;// for (int i = 0; i < coins.length; i++){// int temp = coinChange(coins, amount - coins[i]);// if (temp == -1){continue;}// min = Math.min(min, temp + 1);// }// return min == Integer.MAX_VALUE ? -1 : min;} }
最长递增子序列
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
示例 1:
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
示例 2:输入:nums = [0,1,0,3,2,3]
输出:4
示例 3:输入:nums = [7,7,7,7,7,7,7]
输出:1来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-increasing-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。class Solution {public int lengthOfLIS(int[] nums) {//动态规划if (nums == null || nums.length == 0){return 0;}//求最优解,利用dp,输出为长度,故new一维dp数组,dp[i]初始为1,状态为nums[i]和nums[j]大小比较,更新状态值//dp[i]表示的是长度为i + 1的数组最大递增子序列int len = nums.length;int result = 1;int []dp = new int[len + 1];Arrays.fill(dp, 1); //填充dp数组,全部为1for (int i = 1; i < len; i++){for (int j = 0; j < i; j++){if (nums[j] < nums[i]){ //判断条件dp[i] = Math.max(dp[i], dp[j] + 1); //状态转移}result = Math.max(dp[i], result); //由于有子问题最大值,故设立变量result更新最大值}}return result; //输出dp[len - 1]为长度为len - 1的数组最大递增子序长度} }
爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。- 1 阶 + 1 阶
- 2 阶
示例 2:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。- 1 阶 + 1 阶 + 1 阶
- 1 阶 + 2 阶
- 2 阶 + 1 阶
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/climbing-stairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {public int climbStairs(int n) {//dp[i] 表示的是爬到第i阶方法数int []dp = new int[n + 1];dp[0] = 1; //初始化dp[0]为1——>以至于后面for循环dp[2]能够得出正确答案,只要1和2是正确答案,后面可得正确取值dp[1] = 1; for (int i = 2; i <= n; i++){dp[i] = dp[i - 1] + dp[i - 2]; //分为1步和2步两种情况,并且求种数,为两者之和}return dp[n];} }
总结:看完这几道例题,大家也许会发现主要还是dp一维数组,并且算是比较简单的,但是对于刚开始入门动规的话,应该能够起到一定的作用,力扣上面也有一个动态规划计划集,我暂时也是根据上面做的。大家有兴趣可以去跟着做一做。如有不足,请与我联系更改。
我把链接放在这里,大家有兴趣可以试试:力扣-动态规划入门
初识动态规划(一)简单入门动态规划与上手操作相关推荐
- 通过金矿模型介绍动态规划(经典入门)
对于动态规划,每个刚接触的人都需要一段时间来理解,特别是第一次接触的时候总是想不通为什么这种方法可行,这篇文章就是为了帮助大家理解动态规划,并通过讲解基本的01背包问题来引导读者如何去思考动态规划.本 ...
- 【动态规划】简单背包问题II
问题 J: [动态规划]简单背包问题II 时间限制: 1 Sec 内存限制: 64 MB 提交: 127 解决: 76 [提交] [状态] [讨论版] [命题人:admin] 题目描述 张琪曼:& ...
- 从入门到入土:Python爬虫学习|Selenium自动化模块学习|简单入门|轻松上手|自动操作浏览器进行处理|chrome|PART01
此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) 本人博客所有文章纯属学习之用,不涉及商业利益.不合适引用,自当删除! 若 ...
- 一个简单的动态规划问题---小偷案例
Java算法训练-小偷案例 文章目录 Java算法训练---小偷案例 前言 一.案例描述 二.问题分析 三.代码示例 总结 前言 动态规划是一种算法技巧,先举一个例子: 如何让一个四岁的小孩理解动 ...
- 题解:魔法少女(动态规划超简单)
前些时间虚渊玄的巨献小圆着实火了一把.在黑长直(小炎)往上爬楼去对抗魔女之夜时,她遇到了一个问题想请你帮忙.因为魔女之夜是悬浮在半空的,所以她必须要爬楼,而那座废墟一共有 nn 层,而且每层高度不同, ...
- 动态规划走楼梯_动态规划问题为什么要画表格?
❝ 本文是我的 91 算法第一期的部分讲义内容.91 算法第一期已经接近尾声,二期的具体时间关注我的公众号即可,一旦开放,会第一时间在公众号<力扣加加>通知大家. ❞ 动态规划可以理解为是 ...
- [MVC.NET] Asp.Net MVC3 简单入门第一季
转自:http://www.cnblogs.com/fly_dragon/archive/2011/10/12/2208042.html 初识Asp.Net MVC2.0 初识Asp.Net MVC2 ...
- Matlab 界面设计简单入门(App Designer)
新版Matlab交互界面基本操作 注意:本教程仅适用于2016b以后版本,建议安装2019b以后最新版本Matlab 与原来的GUIDE不同,新版的App Designer程序编写更加合理,更加好看, ...
- 【CMS建站】写给大家看的网站制作教程03—零基础学网站制作的简单入门指南...
作者 | 杨小爱 来源 | web前端开发(ID:web_qdkf) 在上一篇<[CMS建站]写给大家看的网站制作教程02-网站制作的工具介绍与下载安装>文章中,我详细的讲解了关于制作一个 ...
最新文章
- js解决异步的方法汇总
- 如何为程序分配合适的栈空间?
- opengl win32 nehe
- 计算机专业哪些证书可以抵个税,2020年度个人所得税汇算清缴进行时 职业资格证书有哪些能抵扣个税?...
- 一个介绍傅立叶变换的好文章
- map怎么转化dto_阿里面试:为什么Map桶中个数超过8才转为红黑树
- golang语言的类型
- 全卷机神经网络图像分割(U-net)-keras实现
- 18-黑马程序员------OC语言学习笔记---封装
- 计算机网络实验报告 接墙上的,计算机网络实验报告模板.doc
- C/C++结构体语法总结
- 基于改进麻雀算法优化变分模态分解(IAMSSA—VMD)的信号分解方法
- 代码检测vc2013环境是否已经安装了
- Java学习笔记:根据Excel工资表生成工资条
- 最小生成树详解(模板 + 例题)
- 浅谈利用强化学习A3C玩转超级玛丽奥
- 及时复盘的好处_及时复盘,促进成长
- Python+bs4实现爬取小说并下载到本地
- Pod2g已发现可完美越狱iOS 5的漏洞
- 成都中医药大学计算机基础试题,成都中医药大学2016年春季学期期末考试计算机基础-成教()解剖.doc...