动态规划

动态规划-Last Stone Weight II

谁说胖子不能爱 提交于 2020-01-11 18:31:21
2020-01-11 17:47:59 问题描述: 问题求解: 本题和另一题target sum非常类似。target sum的要求是在一个数组中随机添加正负号,使得最终得到的结果是target,这个题目被证明和背包问题是同一个问题,只是需要进行一下转化。 本题其实也是一个套壳题目,只是这次的壳套的更加隐蔽,对于本题来说,其实核心就是将其划分成两个堆,我们需要的是两堆的diff最小。 那么就需要另一个技巧了,我们不会直接使用dp去求这个最小值,而是使用dp去判断对于小堆中的和的可能性,最后在遍历检索一遍得到最小的diff即可。 public int lastStoneWeightII(int[] stones) { int n = stones.length; int sum = 0; for (int num : stones) sum += num; int[] dp= new int[sum / 2 + 1]; dp[0] = 1; for (int i = 0; i < n; i++) { for (int w = sum / 2; w >= 0; w--) { if (stones[i] <= w) dp[w] = dp[w] + dp[w - stones[i]]; } } int res = Integer.MAX_VALUE; for (int i = 0; i <

力扣刷题 | 动态规划问题

℡╲_俬逩灬. 提交于 2020-01-11 09:39:11
文章目录 总述 总结 5 最长回文子串 53 最大子序和 62 不同路径 63 不同路径2 64 最小路径和 70 爬楼梯 91 编码方法 95 不同的二叉搜索树2 96 不同的二叉搜索树 120 三角形最小路径和 121 买卖股票的最佳时机 122 买卖股票的最佳时机2 123 买卖股票的最佳时机3 139 单词拆分 总述 动态规划(英语:Dynamic programming,简称 DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。 动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再根据子问题的解以得出原问题的解。动态规划往往用于优化递归问题,例如斐波那契数列,如果运用递归的方式来求解会重复计算很多相同的子问题,利用动态规划的思想可以减少计算量。 通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,具有天然剪枝的功能,从而减少计算量:一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。 总结 动态规划适用于有重复的子问题的情况

Leetcode 动态规划

痞子三分冷 提交于 2020-01-11 07:09:09
打家劫舍 题目描述:用一个数组表一排房屋中的金钱数量,强盗想要抢到最多的金钱,但是唯一的限制是不能抢相邻的房子,求强盗能抢到的最大数额: 用dp数组记录截至到第n间房最多可以抢到多少钱 public int rob ( int [ ] nums ) { int len = nums . length ; if ( len == 0 ) return 0 ; if ( len == 1 ) return nums [ 0 ] ; int [ ] temp = new int [ len ] ; //temp[n]表示在n及之前房屋中能抢到最多的钱 temp [ 0 ] = nums [ 0 ] ; temp [ 1 ] = Math . max ( nums [ 0 ] , nums [ 1 ] ) ; for ( int i = 2 ; i < len ; i ++ ) { temp [ i ] = Math . max ( nums [ i ] + temp [ i - 2 ] , temp [ i - 1 ] ) ; } return Math . max ( temp [ len - 1 ] , temp [ len - 2 ] ) ; } 最长上升序列: 如[10,9,2,5,3,7,101,18],最长上升子序列是[2,3,7,101],输出最长上升序列长度;

c++ 动态规划-01背包

∥☆過路亽.° 提交于 2020-01-10 03:28:57
动态规划 - 01背包问题 1.使用递归遍历(穷举)求解: 01背包问题:给定 n 种物品和一个重量(容量)(限定条件)为 w 的 背包 ,物品 i 的重量是 wi,其价值为 vi。(每种物品只有一个)问:如何选择装入 背包 的物品,使得装入 背包 中的物品的价值最大。 //VC6.0-------------------------- #include"stdafx.h" #include <cmath> #include <iostream> using namespace std; //----------全局变量------------ #define n 4 //number //物品数量 #define max_w 9 //weight //可承受重量(最大重量) int value[n]={2,3,4,5}; //物品价值 int weight[n]={3,4,5,6}; //物品重量 //最大价值 以及解向量 int max_v=0; int x[n]={0}; int nx[n]={0}; //当前解的情况 //-----------------------递归----------------------- void beibao01(int i,int v,int w) //第i个物品 总价值 总重量 { //物品已遍历完毕 if(i>n-1) return;

动态规划和分治法的区别

你离开我真会死。 提交于 2020-01-09 20:59:05
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 动态规划也是一种分治思想(比如其状态转移方程就是一种分治),但与分治算法不同的是,分治算法是把原问题分解为若干个子问题,自顶向下求解子问题,合并子问题的解,从而得到原问题的解。动态规划也是把原始问题分解为若干个子问题,然后自底向上,先求解最小的子问题,把结果存在表格中,在求解大的子问题时,直接从表格中查询小的子问题的解,避免重复计算,从而提高算法效率。 (1)最优子结构 是指问题的最优解包含其子问题的最优解。最有子结构是使用动态规划的最基本的条件,如果不具有最优子结构性质,就不可以使用动态规划解决。 证明的例子 (2) 子问题重叠 子问题重叠不是使用动态规划的必要条件,但是问题存在子问题重叠的特性更能够充分彰显动态规划的优势。 举个例子:求斐波那契数列时fib(8)=fib(7)+fib(6),其中fib(8)的最优解就包含了子问题fib(7)的最优解和子问题fib(6)的最优解,反过来讲只要我们求解出子问题的最优解,那么就可以构造出问题的最优解,这也就是为什么最优子结构是求解动态规划的必要条件。fib(7)和fib(6)中有相同的子问题fib(5),这就是子问题重叠。 (3) 动态规划的维数 斐波那契数列问题中的递归方程中只涉及一个变量i,所以是一维的动态规划,最长公共子序列问题中,递归方程中涉及两个变量

动态规划之编辑距离

半腔热情 提交于 2020-01-08 11:53:32
#提前声明:转载自 #https://www.jianshu.com/p/a617d20162cf #给定两个字符串Word1,word2,求出word1变成Word2所需要的最小编辑次数 #文章里面详细介绍了编辑距离的思想,Python代码实现,简单应用~ 来源: https://www.cnblogs.com/xiaodangdang/p/12165303.html

动态规划题目(C语言)

百般思念 提交于 2020-01-07 21:59:04
70 . 爬楼梯 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数。 示例 1: 输入: 2 输出: 2 解释: 有两种方法可以爬到楼顶。 1. 1 阶 + 1 阶 2. 2 阶 示例 2: 输入: 3 输出: 3 解释: 有三种方法可以爬到楼顶。 1. 1 阶 + 1 阶 + 1 阶 2. 1 阶 + 2 阶 3. 2 阶 + 1 阶 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/climbing-stairs int climbStairs(int n){ if(n==1)return 1; int dp[n+1]; dp[1]=1; dp[2]=2; for(int i=3;i<n+1;i++){ dp[i]=dp[i-1]+dp[i-2]; } return dp[n]; } 62. 不同路径 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。 问总共有多少条不同的路径? 例如,上图是一个7 x 3 的网格。有多少可能的路径? 说明:m 和 n 的值均不超过 100。 示例 1:

动态规划3-贪心算法-0-1背包

拈花ヽ惹草 提交于 2020-01-07 21:28:29
参考 https://zh.wikipedia.org/wiki/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95 贪心算法 (英语: greedy algorithm),又称 贪婪算法 ,是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的 算法 。 [1] 比如在 旅行推销员问题 中,如果旅行员每次都选择最近的城市,那这就是一种贪心算法。 贪心算法在有最优子结构的问题中尤为有效。最优子结构的意思是局部最优解能决定全局最优解。简单地说,问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。 贪心算法与 动态规划 的不同在于它对每个子问题的解决方案都做出选择,不能回退。动态规划则会保存以前的运算结果,并根据以前的结果对当前进行选择,有回退功能。 贪心法可以解决一些 最优化 问题,如:求 图 中的 最小生成树 、求 哈夫曼编码 ……对于其他问题,贪心法一般不能得到我们所要求的答案。一旦一个问题可以通过贪心法来解决,那么贪心法一般是解决这个问题的最好办法。由于贪心法的高效性以及其所求得的答案比较接近最优结果,贪心法也可以用作辅助算法或者直接解决一些要求结果不特别精确的问题。 贪心算法,可以针对一些不是特别复杂的问题,也就是不需要推导重来,确定子结构最优解,这个最优解就是最终解的一部分,不会像动态规划中

怎么找卖百度云资源的

老子叫甜甜 提交于 2020-01-07 13:44:32
【十 薇:PPS33A】【诚信经营】【持续更新】【品种繁多】【任意挑选】【质量有保障】由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过不错的文章给大家。大家也可以留言区补充。 一、算法最最基础 1、时间复杂度 2、空间复杂度 一般最先接触的就是时间复杂度和空间复杂度的学习了,这两个概念以及如何计算,是必须学的,也是必须最先学的,主要有最大复杂度、平均复杂度等,直接通过博客搜索学习即可。 文章推荐: 算法分析神器—时间复杂度 二、基础数据结构 1、线性表 列表(必学) 链表(必学) 跳跃表(知道原理,应用,最后自己实现一遍) 并查集(建议结合刷题学习) 不用说,链表、列表必须,不过重点是链表。 三分钟基础数据结构:如何轻松手写链表? 以后有面试官问你「跳跃表」,你就把这篇文章扔给他 2、栈与队列 栈(必学) 队列(必学) 优先队列、堆(必学) 多级反馈队列(原理与应用) 特别是优先队列,再刷题的时候,还是经常用到的,队列与栈

动态规划-Minimum Insertion Steps to Make a String Palindrome

拜拜、爱过 提交于 2020-01-07 01:25:56
2020-01-05 11:52:40 问题描述: 问题求解: 好像多次碰到类似的lcs的变种题了,都是套上了回文的壳。这里再次记录一下。 其实本质就是裸的lcs,就出结果了。 public int minInsertions(String s) { StringBuffer sb = new StringBuffer(s); String b = sb.reverse().toString(); return s.length() - lcs(s, b); } public int lcs(String str1, String str2) { int len1 = str1.length(); int len2 = str2.length(); int c[][] = new int[len1+1][len2+1]; for (int i = 0; i <= len1; i++) { for( int j = 0; j <= len2; j++) { if(i == 0 || j == 0) { c[i][j] = 0; } else if (str1.charAt(i-1) == str2.charAt(j-1)) { c[i][j] = c[i-1][j-1] + 1; } else { c[i][j] = Math.max(c[i - 1][j], c[i][j - 1]