动态规划

LeetCode:78 子集 动态规划思想

孤人 提交于 2020-02-27 04:05:31
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。 说明:解集不能包含重复的子集。 示例: 输入 : nums = [ 1 , 2 , 3 ] 输出 : [ [ ] , [ 1 ] , [ 2 ] , [ 1 , 2 ] , [ 3 ] , [ 1 , 3 ] , [ 2 , 3 ] , [ 1 , 2 , 3 ] ] 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/subsets 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 思路 因为 给定的数组不包含重复元素 ,那么从前往后取元素,每取一个元素x,对答案中的所有集合都加上x,并把【加入x后的集合】加入到答案之中即可 动态规划: 已知前 i-1 个元素的所有子集,那么 前 i 个元素的所有子集,就是 【前 i-1 个元素的所有子集】+ 【前 i-1 个元素的所有子集,都加上第 i 个元素形成的新集】 注意:初始的答案集合为空,即 [[]] 代码 class Solution { public : vector < vector < int >> subsets ( vector < int > & nums ) { vector < vector < int >> ans ; ans . push_back ( { } )

(基础)01背包问题

风流意气都作罢 提交于 2020-02-26 23:38:41
问题描述 有n个物品,它们有各自的体积ci和价值wi,现有给定容量的背包v,如何让背包里装入的物品具有最大的价值总和? 原理:   动态规划与分治法类似,都是把大问题拆分成小问题,通过寻找大问题与小问题的递推关系,解决一个个小问题,最终达到解决原问题的效果。但不同的是,分治法在子问题和子子问题等上被重复计算了很多次,而动态规划则具有 记忆性 ,通过填写表把所有已经解决的子问题答案纪录下来,在新问题里需要用到的子问题可以直接提取,避免了重复计算,从而节约了时间,所以在问题满足最优性原理之后,用动态规划 解决问题的核心就在于填表 ,表填写完毕,最优解也就找到。 思路:   i为遍历的每一个物品,j为遍历0到v的体积,如果可以装下,由于装下不一定使总和最大,则装下即为dp[i-1][j-c[i]]+w[i],不装为dp[i-1][j],取两者中较大者。 j-c[i]表示为目前物品空出空间,剩下的空间的价值取 之前可用空间下的最大值。     由此可以得出递推关系式:     1) j<c(i) dp(i,j)=dp(i-1,j)     2) j>=c(i) dp(i,j)=max { dp (i-1,j) , dp(i-1,j-c(i))+w(i) } 输入: 5 10 2 1 3 5 2 5 3 4 4 3 输出: 9 #include <stdio.h> #include

1068 Find More Coins (30分)

痴心易碎 提交于 2020-02-26 11:52:59
题目 Eva loves to collect coins from all over the universe, including some other planets like Mars. One day she visited a universal shopping mall which could accept all kinds of coins as payments. However, there was a special requirement of the payment: for each bill, she must pay the exact amount. Since she has as many as 1 0 4 10^4 1 0 4 coins with her, she definitely needs your help. You are supposed to tell her, for any given amount of money, whether or not she can find some coins to pay for it. Input Specification: Each input file contains one test case. For each case, the first line

动态规划

浪子不回头ぞ 提交于 2020-02-26 03:10:44
动态规划表格之经典算法-01背包 import java . util . Scanner ; public class Main60 { //动态规划 public static void main ( String [ ] args ) { Scanner sc = new Scanner ( System . in ) ; int n = sc . nextInt ( ) ; //商品个数 int m = sc . nextInt ( ) ; //背包容量 int [ ] w = new int [ n + 1 ] ; //重量 int [ ] v = new int [ n + 1 ] ; //价格 int [ ] [ ] tab = new int [ m + 1 ] [ m + 1 ] ; for ( int i = 1 ; i <= n ; i ++ ) { w [ i ] = sc . nextInt ( ) ; v [ i ] = sc . nextInt ( ) ; } //tab首行 首列为0 for ( int i = 0 ; i <= n ; i ++ ) { for ( int j = 0 ; j <= m ; j ++ ) { if ( j == 0 || i == 0 ) { tab [ i ] [ j ] = 0 ; } } } //循环填写表格

算法常见概念

僤鯓⒐⒋嵵緔 提交于 2020-02-25 08:02:22
一个算法应该具有以下五个重要的特征: 1、有穷性: 一个算法必须保证执行有限步之后结束; 2、确切性: 算法的每一步骤必须有确切的定义; 3、输入:一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法本身定除了初始条件; 4、输出:一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的; 5、可行性: 算法原则上能够精确地运行,而且人们用笔和纸做有限次运算后即可完成。 常见的算法 1.分治法 字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法( 快速排序 、 归并排序 )、 傅立叶变换 ( 快速傅立叶变换 )。另一方面,理解及设计分治法算法的能力需要一定时间去掌握。正如以归纳法去证明一个 理论 ,为了使递归能够推行,很多时候需要用一个较为概括或复杂的问题去取代原有问题。而且并没有一个系统性的方法去适当地概括问题。 2.动态规划法 动态规划在查找有很多 重叠子问题 的情况的最优解时有效。它将问题重新组合成子问题。为了避免多次解决这些子问题,它们的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。因此,动态规划保存递归时的结果,因而不会在解决同样的问题时花费时间。 动态规划只能应用于有

70. 爬楼梯

人盡茶涼 提交于 2020-02-25 01:25:10
文章目录 leetcode70:[70. 爬楼梯](https://leetcode-cn.com/problems/climbing-stairs/) 题目描述 solution idea 动态规划 斐波那契数列 参考文献 leetcode70: 70. 爬楼梯 题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? **注意:**给定 n 是一个正整数。 Example 输入: 5 输出: 8 solution idea 动态规划 不难发现,这个问题可以被分解为一些包含最优子结构的子问题,即它的最优解可以从其子问题的最优解来有效地构建,我们可以使用动态规划来解决这一问题。 第 i 阶可以由以下两种方法得到: 在第 (i-1) 阶后向上爬一阶。 在第 (i-2) 阶后向上爬 2 阶。 所以到达第 i 阶的方法总数就是到第 (i-1) 阶和第 (i-2) 阶的方法数之和。 令 dp[i] 表示能到达第 i 阶的方法总数:$ dp[i]=dp[i-1]+dp[i-2] $ class Solution { /* ** 动态规划 */ public: int climbStairs(int n) { if(n==1) return 1; if(n==2) return 2; int dp[n]; dp[0]=1;

96. 不同的二叉搜索树(Java)

北战南征 提交于 2020-02-25 00:48:50
1 题目 2 Java 本题虽然是树的递归,但可以看做动态规划 原因是常规树的递归每个子问题的结果都不一样,无法建立备忘录优化 本题只求个数,[1,2,3]和[2,3,4]两组构成二叉树的数量是一样的,可以建立备忘录优化 2.1 方法一(递归;可看做动态规划) numi = (num1 * num2)i代表: i为选定的根节点,0 ~ i-1作为左子树,i+1 ~ n是右子树,且0 ~ i-1构成二叉搜索树数量为num1,i+1 ~ n构成二叉搜索树数量为num2 0 ~ n节点组成的二叉搜索树数量num = num1+num2+num3……nunn class Solution { public int numTrees ( int n ) { if ( n == 0 || n == 1 ) return 1 ; int ans = 0 ; for ( int i = 1 ; i <= n ; i ++ ) { ans += numTrees ( i - 1 ) * numTrees ( n - i ) ; } return ans ; } } 2.2 方法二(优化递归;自顶向下) 带备忘录的递归 class Solution { public int numTrees ( int n ) { int [ ] memory = new int [ n + 1 ] ; return

【作业】算法第三章作业

╄→гoц情女王★ 提交于 2020-02-23 10:30:46
(1) 你对动态规划算法的理解 动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有 最优值 的解。动态规划算法与 分治法 类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从 这些子 问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。具体的动态规划算法多种多样,但它们具有相同的填表格式。 (2)分别列出编程题1、2的递归方程 编程题1: d[i]=max(d[i],d[j]+1) 编程题2: cost[i][j]=m[j]+cost[j][i] (3)说明结对编程情况 我与菲凡两个人在做题的时候经常会进入激烈的探讨,互相谁也不服谁,就差大一架,但是感觉正是有这样的讨论,才让我们在互相进步,互相get到对方的idea。感觉这样的方法比自己一个人做来的更有趣更有意义。 来源: https://www.cnblogs

【算法导论】贪心算法,递归算法,动态规划算法总结

主宰稳场 提交于 2020-02-23 10:26:55
一般实际生活中我们遇到的算法分为四类: 一>判定性问题 二>最优化问题 三>构造性问题 四>计算性问题 而今天所要总结的算法就是着重解决 最优化问题 《算法之道》对三种算法进行了归纳总结,如下表所示: 标准分治 动态规划 贪心算法 适用类型 通用问题 优化问题 优化问题 子问题结构 每个子问题不同 很多子问题重复(不独立) 只有一个子问题 最优子结构 不需要 必须满足 必须满足 子问题数 全部子问题都要解决 全部子问题都要解决 只要解决一个子问题 子问题在最优解里 全部 部分 部分 选择与求解次序 先选择后解决子问题 先解决子问题后选择 先选择后解决子问题 分治算法特征: 1)规模如果很小,则很容易解决。//一般问题都能满足 2)大问题可以分为若干规模小的相同问题。//前提 3)利用子问题的解,可以合并成该问题的解。//关键 4)分解出的各个子问题相互独立,子问题不再包含公共子问题。 //效率高低 【一】动态规划: 依赖:依赖于有待做出的最优选择 实质:就是分治思想和解决冗余。 自底向上(每一步,根据策略得到一个更小规模的问题。最后解决最小规模的问题。得到整个问题最优解) 特征:动态规划任何一个i+1阶段都仅仅依赖 i 阶段做出的选择。而与i之前的选择无关。但是动态规划不仅求出了当前状态最优值,而且同时求出了到中间状态的最优值。 缺点:空间需求大。 【二】贪心算法: 依赖

【算法导论】贪心算法,递归算法,动态规划算法总结

痴心易碎 提交于 2020-02-23 10:24:55
一般实际生活中我们遇到的算法分为四类: 一>判定性问题 二>最优化问题 三>构造性问题 四>计算性问题 而今天所要总结的算法就是着重解决 最优化问题 《算法之道》对三种算法进行了归纳总结,如下表所示: 标准分治 动态规划 贪心算法 适用类型 通用问题 优化问题 优化问题 子问题结构 每个子问题不同 很多子问题重复(不独立) 只有一个子问题 最优子结构 不需要 必须满足 必须满足 子问题数 全部子问题都要解决 全部子问题都要解决 只要解决一个子问题 子问题在最优解里 全部 部分 部分 选择与求解次序 先选择后解决子问题 先解决子问题后选择 先选择后解决子问题 分治算法特征: 1)规模如果很小,则很容易解决。//一般问题都能满足 2)大问题可以分为若干规模小的相同问题。//前提 3)利用子问题的解,可以合并成该问题的解。//关键 4)分解出的各个子问题相互独立,子问题不再包含公共子问题。 //效率高低 【一】动态规划: 依赖:依赖于有待做出的最优选择 实质:就是分治思想和解决冗余。 自底向上(每一步,根据策略得到一个更小规模的问题。最后解决最小规模的问题。得到整个问题最优解) 特征:动态规划任何一个i+1阶段都仅仅依赖 i 阶段做出的选择。而与i之前的选择无关。但是动态规划不仅求出了当前状态最优值,而且同时求出了到中间状态的最优值。 缺点:空间需求大。 【二】贪心算法: 依赖