动态规划

浅谈个人学DP的经历和感受

拜拜、爱过 提交于 2020-03-17 02:12:32
动态规划的定义! 首先,我们看一下官方定义: 定义: 动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。 动态规划算法的基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息。在求解任一子问题时,列出各种可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各子问题,最后一个子问题就是初始问题的解。 ———————————————— 版权声明:本文为CSDN博主「BS有前途」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/ailaojie/article/details/83014821 不会也不要急,每个人刚学动态规划的时候都很懵逼!!! 我第一次接触动态规划大概是额,一个月之前了吧,当时老师完全给我讲懵了。然后课听完了脑子一片空白。 然后又请教@SXY大佬开小灶,总算讲明白了一点,但是我还是害怕呀!因为我根本就不熟,所以一个月之内基本没怎么做。 直到今天我觉得是时候解决这个问题了,于是我打开了( 小破谷 )伟大的洛谷,找到了动态规划题单,冒着满头大汉开始了征程…… 个人的理解 上面第一段是动态规划的基本定义(废话)

ACM进阶计划

人盡茶涼 提交于 2020-03-14 11:33:48
ACM进阶计划 ACM队不是为了一场比赛而存在的,为的是队员的整体提高。 大学期间,ACM队队员必须要学好的课程有: l C/C++两种语言 l 高等数学 l 线性代数 l 数据结构 l 离散数学 l 数据库原理 l 操作系统原理 l 计算机组成原理 l 人工智能 l 编译原理 l 算法设计与分析 除此之外,我希望你们能掌握一些其它的知识,因为知识都是相互联系,触类旁通的。 以下学习计划每学期中的内容不分先后顺序,虽说是为立志于学习ACM的同学列的知识清单,但内容不限于ACM的知识。英语之类与专业相距较远的课程请自行分配时间,这里不再列举。 大一上学期: 必学: 1. C语言基础语法必须全部学会 a) 推荐“语言入门”分类20道题以上 b) 提前完成C语言课程设计 2. 简单数学题(推荐“数学”分类20道以上) 需要掌握以下基本算法: a) 欧几里德算法求最大公约数 b) 筛法求素数 c) 康托展开 d) 逆康托展开 e) 同余定理 f) 次方求模 3. 计算几何初步 a) 三角形面积 b) 三点顺序 4. 学会简单计算程序的时间复杂度与空间复杂度 5. 二分查找法 6. 简单的排序算法 a) 冒泡排序法 b) 插入排序法 7. 贪心算法经典题目 8. 高等数学 以下为选修: 9. 学会使用简单的DOS命令(较重要) a) color/dir/copy/shutdown/mkdir

ACM进阶计划

怎甘沉沦 提交于 2020-03-14 11:31:58
ACM进阶计划 ACM 队不是为了一场比赛而存在的,为的是队员的整体提高。 大学期间, ACM 队队员必须要学好的课程有: l C/C++ 两种语言 l 高等数学 l 线性代数 l 数据结构 l 离散数学 l 数据库原理 l 操作系统原理 l 计算机组成原理 l 人工智能 l 编译原理 l 算法设计与分析 除此之外,我希望你们能掌握一些其它的知识,因为知识都是相互联系,触类旁通的。 以下学习计划每学期中的内容不分先后顺序,虽说是为立志于学习 ACM 的同学列的知识清单,但内容不限于 ACM 的知识。英语之类与专业相距较远的课程请自行分配时间,这里不再列举。 大一上学期: 必学: 1. C 语言基础语法必须全部学会 a) 推荐“语言入门”分类 20 道题以上 b) 提前完成 C 语言课程设计 2. 简单数学题(推荐“数学”分类 20 道以上) 需要掌握以下基本算法: a) 欧几里德算法求最大公约数 b) 筛法求素数 c) 康托展开 d) 逆康托展开 e) 同余定理 f) 次方求模 3. 计算几何初步 a) 三角形面积 b) 三点顺序 4. 学会简单计算程序的时间复杂度与空间复杂度 5. 二分查找法 6. 简单的排序算法 a) 冒泡排序法 b) 插入排序法 7. 贪心算法经典题目 8. 高等数学 以下为选修: 9. 学会使用简单的 DOS 命令(较重要) a) color/dir

动态规划算法(@背包问题)

早过忘川 提交于 2020-03-14 08:24:01
 动态规划(Dynamic programming)是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。    动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。 通常许 多 子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同 一个 子问题解之时直接查表。 这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。   关于动态规划最经典的问题当属背包问题。 算法步骤: 1. 最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。 2. 子 问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多 次。 动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题 时,只是 在表格中简单地查看一下结果

结巴分词原理介绍

笑着哭i 提交于 2020-03-14 03:43:35
转自一个很不错的博客,结合自己的理解,记录一下。作者:zhbzz2007 出处: http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明。谢谢! https://www.cnblogs.com/zhbzz2007/p/6076246.html?utm_source=itdadao&utm_medium=referral 结巴分词的原理,结合一个面试题:有一个词典,词典里面有每个词对应的权重,有一句话,用这个词典进行分词,要求分完之后的每个词都必须在这个词典中出现过,目标是让这句话的权重最大。 涉及算法: 基于前缀词典实现词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图(DAG),采用动态规划查找最大概率路径,找出基于词频的最大切分组合; 对于未登录词,采用了基于汉字成词能力的 HMM模型,采用Viterbi算法进行计算; 基于Viterbi算法的词性标注; 分别基于tfidf和textrank模型抽取关键词; 基于前缀词典及动态规划实现分词 http://www.cnblogs.com/zhbzz2007/p/6084196.html jieba分词主要是基于统计词典,构造一个前缀词典;然后利用前缀词典对输入句子进行切分,得到所有的切分可能,根据切分位置,构造一个有向无环图;通过动态规划算法,计算得到最大概率路径

动态规划模型——最长公共子序列(LCS)

走远了吗. 提交于 2020-03-12 14:16:10
给定两个序列,求一个最长的子序列(子序列可以不连续) //最长公共子序列做法 # include <cstdio> # include <vector> using namespace std ; int LCS ( vector < int > & A , vector < int > & B ) { //A为模板串,A,B下标从1开始 vector < vector < int > > dp ( A . size ( ) , vector < int > ( B . size ( ) , 0 ) ) ; //dp[i][j] 表示A[i]和B[j]之前的LCS长 for ( int i = 1 ; i < A . size ( ) ; i ++ ) { for ( int j = 1 ; j < B . size ( ) ; j ++ ) { if ( A [ i ] == B [ j ] ) { dp [ i ] [ j ] = dp [ i - 1 ] [ j - 1 ] + 1 ; } else { if ( dp [ i - 1 ] [ j ] > dp [ i ] [ j - 1 ] ) dp [ i ] [ j ] = dp [ i - 1 ] [ j ] ; else dp [ i ] [ j ] = dp [ i ] [ j - 1 ] ; } } }

区间DP总结

試著忘記壹切 提交于 2020-03-11 13:04:40
一般问题 把相邻符合条件的合并,来获得最优解 概念 区间类型动态规划是线性动态规划的拓展,它在分阶段划分问题时,与阶段中元素出现的顺序和由前一阶段的哪些元素合并而来有很大的关系。(例:f[i][j]=f[i][k]+f[k+1][j]) 区间类动态规划的特点: 合并:即将两个或多个部分进行整合。 特征:能将问题分解成为两两合并的形式。 求解:对整个问题设最优值,枚举合并点,将问题分解成为左右两个部分,最后将左右两个部分的最优值进行合并得到原问题的最优值。 DP(n^3) DP+四边形不等式优化(n^2) 一般数据500还能跑跑,如果1e3基本凉了,要优化到O(n 2 ),要用到四边形不等式优化。暂时不会,再等等吧, 某博主的证明四边形不等式优化 cin >> n ; memset ( dp , inf ) ; ///初始化dp数组 for ( int i = 1 ; i <= n ; ++ i ) cin >> a [ i ] , pre [ i ] = pre [ i - 1 ] + a [ i ] , dp [ i ] [ i ] = 0 ; for ( int len = 1 ; len < n ; ++ len ) ///枚举区间长度 { for ( int i = 1 ; i + len <= n ; ++ i ) ///枚举区间起点 { int j = i + len

最大子段和-动态规划

痞子三分冷 提交于 2020-03-11 01:05:53
最大子段和-动态规划写法 题目: 法一: 题目: 给定长度为n的整数序列,a[1…n], 求[1,n]某个子区间[i , j]使得a[i]+…+a[j]和最大.或者求出最大的这个和.例如(-2,11,-4,13,-5,2)的最大子段和为20,所求子区间为[2,4]。 有俩种dp做法: 法一: 用数组dp,这里可以假设dp[i]是最大字段和的最后一个,那么他肯定是前面的dp[i-1]和此位置的a[i]结合,或者是a[i]。 例如(-2,11,-4,13,-5,2),这里我是下标从1开始,dp[0]的初值为无穷小,所以dp[1]就可以和dp[0]+a[1]和a[1]进行比较。所以此时dp[1]=-2,然后dp[2]的值就是11,以此类推dp[3]的值是7,dp[4]的值是20,dp[5]的值是15,dp[6]的值是17,得出dp方程为dp[i]=max(dp[i],d[i-1]+a[i])。 # include <stdio.h> # include <iostream> # include <algorithm> # include <string.h> # include <queue> # include <map> # include <math.h> # include <set> # include <vector> # define ll long long using

动态规划之背包问题

雨燕双飞 提交于 2020-03-10 13:28:13
后台天天有人问背包问题,这个问题其实不难啊,如果我们号动态规划系列的十几篇文章你都看过,借助框架,遇到背包问题可以说是手到擒来好吧。无非就是状态 + 选择,也没啥特别之处嘛。 今天就来说一下背包问题吧,就讨论最常说的 0-1 背包问题。描述: 给你一个可装载重量为 W 的背包和 N 个物品,每个物品有重量和价值两个属性。其中第 i 个物品的重量为 wt[i] ,价值为 val[i] ,现在让你用这个背包装物品,最多能装的价值是多少? 举个简单的例子,输入如下: N = 3, W = 4 wt = [2, 1, 3] val = [4, 2, 3] 算法返回 6,选择前两件物品装进背包,总重量 3 小于 W ,可以获得最大价值 6。 题目就是这么简单,一个典型的动态规划问题。这个题目中的物品不可以分割,要么装进包里,要么不装,不能说切成两块装一半。这就是 0-1 背包这个名词的来历。 解决这个问题没有什么排序之类巧妙的方法,只能穷举所有可能,根据我们「动态规划详解」中的套路,直接走流程就行了。 动规标准套路 看来我得每篇动态规划文章都得重复一遍套路,历史文章中的动态规划问题都是按照下面的套路来的。 第一步要明确两点,「状态」和「选择」 。 先说状态,如何才能描述一个问题局面?只要给几个物品和一个背包的容量限制,就形成了一个背包问题呀。 所以状态有两个,就是「背包的容量」和

贪婪算法核心

我与影子孤独终老i 提交于 2020-03-09 19:39:22
通常解决并理解一个动态规划问题需要以下 4 个步骤: 利用递归回溯解决问题 利用记忆表优化(自顶向下的动态规划) 移除递归的部分(自底向上的动态规划) 使用技巧减少时间和空间复杂度 来源: https://www.cnblogs.com/ZJPaang/p/11638557.html