动态规划

动态规划

有些话、适合烂在心里 提交于 2019-12-16 05:29:00
#L2-001 紧急救援 (25分) 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。 输入格式: 输入第一行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0 ~ (N−1);M是快速道路的条数;S是出发地的城市编号;D是目的地的城市编号。 第二行给出N个正整数,其中第i个数是第i个城市的救援队的数目,数字间以空格分隔。随后的M行中,每行给出一条快速道路的信息,分别是:城市1、城市2、快速道路的长度,中间用空格分开,数字均为整数且不超过500。输入保证救援可行且最优解唯一。 输出格式: 第一行输出最短路径的条数和能够召集的最多的救援队数量。第二行输出从S到D的路径中经过的城市编号。数字间以空格分隔,输出结尾不能有多余空格。 输入样例: 4 5 0 3 20 30 40 10 0 1 1 1 3 2 0 3 3 0 2 2 2 3 2 输出样例: 2 60 0 1 3 # include <cstdio> # include <algorithm> # define num 505 using

【图解】从一道动态规划题带你领略『卡特兰数』是如何秒杀算法题的

痞子三分冷 提交于 2019-12-16 03:52:59
一、 leetcode 96 号题 题目链接:https://leetcode-cn.com/problems/unique-binary-search-trees/ 题意:给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种? n = 3 时: 二、动态规划 思路:从 1 开始到 n ,每次以这个数为根,左子树存放比它小的数,右子树存放比它大的数。每个根不重复,因此每个树也必定不重复。 左子树和右子树,又可以按照这个规则去生成新的树。 例如:n = 3的时候 1为根: 比 1 小的数只有 0,不用管。比 1 大的数有 2 和 3。 拿 2 和 3 来生成一棵树和拿 1 和 2 来生成一棵树的种数是不是相同的?那么 1 和 2 能生成多少种树呢? 2为根: 比 2 小的是 1,比 2 大的是 3。这里只有 1 种。 3为根: 比 3 小的是 1 和 2,1 和 2 能生成多少种树呢? 我们先暂停思维,来到一个新的问题。 n = 2 的时候,结果应该是多少? n = 2 的时候,按照我们之前的方法。 1 为根:比 1 大的数只有 2, 这里有 1 种。 2 为根:比 2 小的数只有 1, 这里有 1 种。 那答案就应该是 2 种。 解决了 n = 2 的问题,那 n = 3 的问题就也解决了。 ans = 2 + 1 + 2 = 5。 我们来看一般情况。输入一个 n 。

动态规划之背包问题

让人想犯罪 __ 提交于 2019-12-15 13:13:53
背包问题是动态规划的一个分支,这里先简单介绍一下动态规划的思想。 动态规划程序设计是对解最优化问题的一种途径、一种方法,而不是一种特殊算法。不像搜索或数值计算那样,具有一个标准的数学表达式和明确清晰的解题方法。动态规划程序设计往往是针对一种最优化问题,由于各种问题的性质不同,确定最优解的条件也互不相同,因而动态规划的设计方法对不同的问题,有各具特色的解题方法,而不存在一种万能的动态规划算法,可以解决各类最优化问题。因此在学习时,除了要对基本概念和方法正确理解外,必需具体问题具体分析处理,以丰富的想象力去建立模型,用创造性的技巧去求解。我们也可以通过对若干有代表性的问题的动态规划算法进行分析、讨论,逐渐学会并掌握这一设计方法。(以上来自百度百科) 简单来说动态规划是一个思想,而不是一个固定的算法模板,我们需要通过这种思想确定状态转移方程(一个好的状态),然后再求解。 动态规划适用于很多情况,其中一些情况被统一划分归类,而背包问题则是一种最为常见的动态规划问题。 背包问题又分为许多种,如:01背包,完全背包等 我们这里介绍最为常见的三种,分别是01背包,完全背包,和多重背包。 1.01背包 这是一个经典的动态规划问题,另外在贪心算法里也有背包问题,至于二者的区别在此就不做介绍了。 题目一般都是有 N件物品和一个容量为 V的背包。第 i件物品的体积是 v[i],价值是 c[i]

动态规划套路详解

故事扮演 提交于 2019-12-14 21:54:21
动态规划套路详解 转自 作者:labuladong 链接:https : / / leetcode - cn . com / problems / coin - change / solution / dong - tai - gui - hua - tao - lu - xiang - jie - by - wei - lai - bu - ke / 来源:力扣(LeetCode) 下面通过对斐波那契数列和这道凑零钱问题详解动态规划。如果只想看本题的答案,请直接翻到最后查看。 动态规划算法似乎是一种很高深莫测的算法,你会在一些面试或算法书籍的高级技巧部分看到相关内容,什么状态转移方程,重叠子问题,最优子结构等高大上的词汇也可能让你望而却步。 而且,当你去看用动态规划解决某个问题的代码时,你会觉得这样解决问题竟然如此巧妙,但却难以理解,你可能惊讶于人家是怎么想到这种解法的。 实际上,动态规划是一种常见的「算法设计技巧」,并没有什么高深莫测,至于各种高大上的术语,那是吓唬别人用的,只要你亲自体验几把,这些名词的含义其实显而易见,再简单不过了。 至于为什么最终的解法看起来如此精妙,是因为动态规划遵循一套固定的流程: 递归的暴力解法 -> 带备忘录的递归解法 -> 非递归的动态规划解法 。这个过程是层层递进的解决问题的过程,你如果没有前面的铺垫,直接看最终的非递归动态规划解法

动态规划经典算法

橙三吉。 提交于 2019-12-13 11:53:56
动态规划经典算法案例 动态规划算法是从暴力搜索算法优化过来的,如果我们不清楚暴力搜索的过程,就难以理解动态规划的实现,当我们了解了动态规划算法的基本原理的文字概述,实现条件之后,这时可能并不是太理解这种思想,去面对实际问题的时候也是无从下手,这个时候我们不能停留在文字层面上,而应该去学习经典动态规划算法的实现,然后倒回来看这些概念,便会恍然大悟。 动态规划算法的难点在于 从实际问题中抽象出动态规划表dp,dp一般是一个数组,可能是一维的也可能是二维的,也可能是其他的数据结构。 动态规划的关键点: 1、最优化原理,也就是最有子结构性质。这指的是一个最优化策略具有这样的性质,无论过去状态和决策如何,对前面的决策所形成的状态而言,余下的决策必须构成最优策略,简单来说就是一个最优化策略的子策略总是最优的,如果一个问题满足最优化原理,就称其有最优子结构性质。 2、无后效性,指的是某个状态下的决策的收益,只与状态和决策相关,与达到该状态的方式无关。 3、子问题的重叠性,动态规划将原来指数级的暴力搜索算法改进到了具有多项式时间复杂度的算法,其中的关键在于解决了荣誉,重复计算的问题,这是动态规划算法的根本目的。 4、总体来说,动态规划算法就是一系列以空间换取时间的算法。 案例一: 有n级台阶,一个人每次上一级或者两级,问有多少种走完n级台阶的方法。 分析

零钱兑换-动态规划

*爱你&永不变心* 提交于 2019-12-13 01:26:30
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。 示例 1: 输入: coins = [1, 2, 5], amount = 11 输出: 3 解释: 11 = 5 + 5 + 1 示例 2: 输入: coins = [2], amount = 3 输出: -1 说明: 你可以认为每种硬币的数量是无限的。 题解 动态规划算法似乎是一种很高深莫测的算法,你会在一些面试或算法书籍的高级技巧部分看到相关内容,什么状态转移方程,重叠子问题,最优子结构等高大上的词汇也可能让你望而却步。 而且,当你去看用动态规划解决某个问题的代码时,你会觉得这样解决问题竟然如此巧妙,但却难以理解,你可能惊讶于人家是怎么想到这种解法的。 实际上,动态规划是一种常见的「算法设计技巧」,并没有什么高深莫测,至于各种高大上的术语,那是吓唬别人用的,只要你亲自体验几把,这些名词的含义其实显而易见,再简单不过了。 至于为什么最终的解法看起来如此精妙,是因为动态规划遵循一套固定的流程:递归的暴力解法 -> 带备忘录的递归解法 -> 非递归的动态规划解法。这个过程是层层递进的解决问题的过程,你如果没有前面的铺垫,直接看最终的非递归动态规划解法,当然会觉得牛逼而不可及了。 当然,见的多了,思考多了

待学

别说谁变了你拦得住时间么 提交于 2019-12-11 19:25:15
转自 hzwer : 1.1 基本数据结构 数组 链表,双向链表 队列,单调队列,双端队列 栈,单调栈 1.2 中级数据结构 堆 并查集与带权并查集 hash 表 自然溢出 双hash 1.3 高级数据结构 树状数组 线段树,线段树合并 平衡树 Treap 随机平衡二叉树 Splay 伸展树 Scapegoat Tree 替罪羊树 块状数组,块状链表 5.* 树套树 线段树套线段树 线段树套平衡树 * 平衡树套线段树 6.可并堆 左偏树 *配对堆 KDtree, 四分树 1.4 可持久化数据结构 可持久化线段树 主席树 可持久化平衡树 可持久化块状数组 1.5 字符串相关算法及数据结构 KMP AC 自动机 后缀数组 *后缀树 *后缀自动机 字典树 Trie manacher 1.6 图论相关 最小生成树 prim kruskal 最短路,次短路,K短路 spfa dijkstra floyd 图的连通 连通分量 割点,割边 网络流 最大流 最小割 费用流 分数规划 树相关 树上倍增,公共祖先 树链剖分 树的分治算法(点分治,边分治,*动态?树分治) 动态树 (LCT,*树分块) 虚树 *prufer编码 拓扑排序 欧拉图 二分图 *KM算法 匈牙利算法 1.7 数学相关 (扩展)欧几里得算法,筛法,快速幂 斐蜀定理 更相减损术 欧拉函数与*降幂大法 费马小定理 排列组合

leetcode 动态规划 63. 不同路径 II

a 夏天 提交于 2019-12-10 08:56:56
题目:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。 现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径? 网格中的障碍物和空位置分别用 1 和 0 来表示。 说明:m 和 n 的值均不超过 100。 示例 1: 输入: [ [0,0,0], [0,1,0], [0,0,0] ] 输出: 2 解释: 3x3 网格的正中间有一个障碍物。 从左上角到右下角一共有 2 条不同的路径: 向右 -> 向右 -> 向下 -> 向下 向下 -> 向下 -> 向右 -> 向右 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/unique-paths-ii 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 代码如下 class Solution { public int uniquePathsWithObstacles ( int [ ] [ ] obstacleGrid ) { int m = obstacleGrid . length ; int n = obstacleGrid [ 0 ] . length ; if ( obstacleGrid [ 0 ] [

53 最大子序列 动态规划

蓝咒 提交于 2019-12-10 04:25:40
动态规划 定义当前最大连续子序列和cur_sum=0cur_sum=0,最大子序和res=nums[0]res=nums[0],数组长度nn 对数组进行遍历,对于nums[i]nums[i],存在两种情况: 若当前最大连续子序列和cur_sum>0cur_sum>0,说明cur_sumcur_sum对后续结果有着正向增益,即能使后续结果继续增大,则继续加和cur_sum=cur_sum+num[i]cur_sum=cur_sum+num[i]。 若当前最大连续子序列和cur_sum<=0cur_sum<=0,说明cur_sumcur_sum对后续结果没有增益或负向增益,即若存在更大的加和,一定是从下一元素开始,加上cur_sumcur_sum,只会使结果更小。因此,令cur_sumcur_sum更新为nums[i]nums[i]。 更新最大子序和resres,res=max(res,cur_sum)res=max(res,cur_sum),始终保留最大结果。 作者:zhu_shi_fu 链接:https://leetcode-cn.com/problems/maximum-subarray/solution/dong-tai-gui-hua-zhu-xing-jie-shi-python3-by-zhu_s/ 来源:力扣(LeetCode) 著作权归作者所有

最长上升子序列——动态规划(C++详解)

自古美人都是妖i 提交于 2019-12-10 04:06:42
题目描述 LIS(Longest Increasing Subsequence)最长上升子序列 一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的。 比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中最长的长度是4,比如子序列(1, 3, 5, 8). 对于给定的序列,求出最长上升子序列的长度。 输入样例 5 4 2 3 1 5 输出样例: 3 题解 最长上升子序列是 动态规划 中一个非常典型的例题,他将动态规划的思想完美的融合进去( 将一个问题划分成若干个最优的子问题,并且子问题的推导均与上一个子问题有关 ) 1 这一题将在下面进行递推式的推导 思路 求解这个问题,我们可以把它分解出来——下一个子序列长度len[i+1]是上一个 最长子序列 的长度加1( a[i+1]>a[j]) (j为前面的子序列的最后一项)或者1( 当前面的所有子序列的最后一项都比a[i+1]大,此时子序列就为他本身,len[i+1]只能为1 ) 这是是什么意思呢 就是将这个子序列长度的状态变化全部用一个len数组存储下来 举个例子 {3,1,4,1,5,9,2,6,5}这个序列的最长上升子序列 i=1 a[1]=3 len[1]=1 序列为 3 i=2 a[2]=1 len[2]=1 序列为1