动态规划

【动态规划】打家劫舍

筅森魡賤 提交于 2020-03-09 12:10:03
【动态规划】打家劫舍 题目描述 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。 输入 2,7,9,3,1 输出 12 基本思路 典型的动态规划,相信有了解的同学很快会写出来。每个房间分成两种情况,劫或不劫。劫则上一家不劫,不劫则劫上一家。 动态转移方程 dp[i]=max(a[i]+dp[i-2],dp[i-1]); # include <bits/stdc++.h> using namespace std ; int main ( ) { int dp [ 100 ] ; int a [ 5 ] = { 2 , 7 , 9 , 3 , 1 } ; dp [ 0 ] = 2 , dp [ 1 ] = 7 ; for ( int i = 2 ; i < 5 ; i ++ ) { dp [ i ] = max ( a [ i ] + dp [ i - 2 ] , dp [ i - 1 ] ) ; } cout << dp [ 4 ] ; } 来源: CSDN 作者: Liquor___ 链接: https://blog.csdn.net/Liquor_

动态规划通用解法总结

穿精又带淫゛_ 提交于 2020-03-09 00:37:02
背景: leetcode刷题遇到动态规划的题目,做不出来时看别人的code,也可以理解,但还是没有找到create solution的技巧,单纯的comprehend and remeber,直到遇到了下面这篇题解,终于形成了自己的动态规划通用解题方法,拿所有easy难度的题目试了下,结果横扫 https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/discuss/108870/Most-consistent-ways-of-dealing-with-the-series-of-stock-problems 在动态规划题目中,变形数量最多的差不多就是股票问题了,上述解法也围绕股票问题展开 根据上述帖子,我总结了动态规划的解题方法如下 Question1:如何识别题目适用于动态规划? 某一过程包含多种状态(情况),后一种状态的生成依赖于前面的情况 Quetion2:如何写动态规划? 1、找出问题中的 状态 (state)和 选择 (choice) 2、用选择去表达状态之间的转移 like below for state1 in state1_list: for state2 in state2_list: for state3 in state3_list: dp

动态规划,0/1背包,完全背包

时光怂恿深爱的人放手 提交于 2020-03-08 21:55:12
动态规划 动态规划问题的一般形式就是求最值。 求解动态规划的核心问题是穷举。 动态规划的穷举有点特别,因为这类问题存在「重叠子问题」,如果暴力穷举的话效率会极其低下,所以需要「备忘录」或者「DP table」来优化穷举过程,避免不必要的计算。 而且,动态规划问题一定会具备「最优子结构」,才能通过子问题的最值得到原问题的最值。 关键就是状态转移方程,写出正确的状态转移方程,才能正确地枚举。 解决问题步骤: 明确「状态」 -> 定义 dp 数组/函数的含义 -> 明确「选择」(做出选择改变当前状态-> 明确 base case。 0/1背包问题 描述: 有N件物品和一个容量为V的背包。第i件物品的费用(即体积,下同)是w[i],价值是val[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 思路: 用动态规划的思路,阶段就是“物品的件数”,状态就是“背包剩下的容量”,那么很显然f [ i , v ] 就设为从前 i 件物品中选择放入容量为 v 的背包最大的价值。那么状态转移方程为: f[i][v]=max{ f[i-1][v],f[i-1][v-w[i]]+val[i] }。 这个方程可以如下解释:只考虑子问题“将前 i 个物品放入容量为 v 的背包中的最大价值”那么考虑如果不放入 i ,最大价值就和 i 无关,就是 f[ i - 1 ][ v ] ,

洛谷P1233 木棍加工

跟風遠走 提交于 2020-03-07 20:50:40
原题 题目描述 一堆木头棍子共有n根,每根棍子的长度和宽度都是已知的。棍子可以被一台机器一个接一个地加工。机器处理一根棍子之前需要准备时间。准备时间是这样定义的: 第一根棍子的准备时间为1分钟; 如果刚处理完长度为L,宽度为W的棍子,那么如果下一个棍子长度为Li,宽度为Wi,并且满足L>=Li,W>=Wi,这个棍子就不需要准备时间,否则需要1分钟的准备时间; 计算处理完n根棍子所需要的最短准备时间。比如,你有5根棍子,长度和宽度分别为(4, 9),(5, 2),(2, 1),(3, 5),(1, 4),最短准备时间为2(按(4, 9)、(3, 5)、(1, 4)、(5, 2)、(2, 1)的次序进行加工)。 输入格式 第一行是一个整数n(n<=5000),第2行是2n个整数,分别是L1,W1,L2,w2,…,Ln,Wn。L和W的值均不超过10000,相邻两数之间用空格分开。 输出格式 仅一行,一个整数,所需要的最短准备时间。 输入输出样例 输入: 5 4 9 5 2 2 1 3 5 1 4 输出: 2 题解 洛谷题解系列好久没更新了,今天写一个,当然这也是我的附属博客中的第一篇题解! 注:附属博客点击侧边栏的手机端按钮即可。 下面正式进入题解部分 先看一下这个题目的标签: 贪心,动态规划 (诶嘿嘿,我最喜欢贪心了) 这个题目有两个属性,长和宽,并且这两个属性都是不上升序列。

浅谈一下这个所谓的特殊算法——动态规划?

人走茶凉 提交于 2020-03-07 04:09:30
转载请标明地址或者附上我的博客地址 https://georgedage.blog.csdn.net/ 前言 最近接了一个项目,有关动态规划,客户提到,动态规划能和spark结合在一起吗?看来或许他对动态规划不是很熟悉,当然,我也不能说自己对其了如指掌,但是我们熟知,当我们说起动态规划的时候,往往是说的动态规划算法。既然是算法,那么它是可以运用到我们的程序中的,当然,前提业务需要,系统需要。 什么是动态规划? 在百度百科中,是这样解释动态规划的: 动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时,提出了著名的最优化原理(principle of optimality), 把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解 ,创立了解决这类过程优化问题的新方法——动态规划。1957年出版了他的名著《Dynamic Programming》,这是该领域的第一本著作。 好像听起来是有点繁琐,当然要这样,这样你就觉得他是比较高大上的了,就像最近《安家》电视剧中所说的——折衷主义,其实不就是混搭吗?那么我们在这高大上的概念中,怎么去理解它呢?

C++:动态规划(2)背包问题

帅比萌擦擦* 提交于 2020-03-06 01:50:07
找这个阶段的状态和上各阶段的状态关系 01背包:每件商品只有一件 dp[i][v]:前i件物品恰好装入v的背包中的最大价值 状态: 放i,求前i-1件商品恰好装入v-w[i]的背包中的最大价值+第i件商品的价值。 不放i,求前i-1件商品恰好装入v的背包中的最大价值。 状态转移方程: 都是求最大价值 dp[i][v]=max( dp[i-1][v] , dp[i-1][v-w[i]]+c[i] ) 通过边界dp[0][v]=0(0<=v<=V) 01背包 二维数组的放与不放 int dp[maxn][maxn]; void _01dp() { int maxd = 0; memset(dp, 0, sizeof(dp)); //边界 for (int i = 0; i < V; i++) { dp[0][i] = 0; } for (int i = 1; i <=N; i++) { for (int v = w[i]; v <= V; v++) { dp[i][v] = max(dp[i - 1][v], dp[i - 1][v - w[i]]+c[i]); maxd = max(maxd, dp[i][v]); } } cout << maxd << endl; } 优化,体积从V-》w[i] 逆序发展 ;不需要物品i了,直接变为有这个商品的体积,和没有 dp[v]=max (

LeetCode.5--最长回文子串

不羁的心 提交于 2020-03-05 23:08:48
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 1: 输入 : "babad" 输出 : "bab" 注意 : "aba" 也是一个有效答案。 示例 2: 输入 : "cbbd" 输出 : "bb" 本文章使用动态规划的方法解决该问题 动态规划问题要解决两个关键点: 一是初始化,初始化用来确定动态规划的起点,也是非常重要的。 二是状态转移。状态转移确定动态规划过程中的状态更新公式。 下面来用动态规划的思想具体分析一下该问题。 首先明确回文字符串的含义 回文字符串: 正着读和反着读都一样的字符串,单个字符也是回文字符串 根据回文字符串的含义,我们可以得出一些初始信息 单个字符为回文子串 两个字符相同为回文子串 寻找状态转移的信息 根据回文字符串的特性,即回文字符串左右两端加上相同的字符组成的新字符串也是回文字符串,具体描述如下 x b x 为 回 文 字 符 串 , 则 y x b x y 也 是 回 文 字 符 串 xbx为回文字符串,则 yxbxy也是回文字符串 x b x 为 回 文 字 符 串 , 则 y x b x y 也 是 回 文 字 符 串 即回文字符串左右两端加上相同字符也是回文字符串。 利用上述的信息可以得出当 字符串左右两端字符相等并且去掉两端字符的字符串为回文字符串,则判断字符为回文字符串。 d p ( i ,

角谷猜想

血红的双手。 提交于 2020-03-05 19:54:59
题目描述 Description 所谓角谷猜想,即给定一个正整数 n,对 n 反复进行下列两种变换: 1)如果n是偶数,就除以2; 2)如果n是奇数,就乘以3加1。 最后的结果总是1。 我们把从 n 变换到 1 所需要进行的变换次数称做 n 的变换长度,如数字 7 的变换为: 7-22-11-34-17-52-26-13-40-20-10-5-16-8-4-2-1 共进行了 16 次变换,因而 7 的变换长度为 16。 Wish 现在对一个给定区间内的最长变换长度比较感兴趣,但是手算起来计算量太大,于是他又找到了参加信息学竞赛的你,你可以帮助他吗? 输入描述 Input Description 每个测试点包含多组数据,第一行一个数 t,表示数据个数。 第二行至第 t+1 行,每行两个数 a、b,表示求 a 和 b 之间数(包含 a、b)的最长变换长度。 输出描述 Output Description 输出格式 t 行,每行输出对应输入数据的各个区间的最长变换长度。 样例输入 Sample Input 2 1 7 9 20 样例输出 Sample Output 16 20 数据范围及提示 Data Size & Hint 数据范围 1 <= t <= 100 1 <= a, b <= 10^8 区间长度不超过 10^5 任何一个大于一的自然数,如果是奇数,则乘以三再加一;如果是偶数

1、算法初识

痴心易碎 提交于 2020-03-05 12:42:10
1.什么是 算法 ? 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。 也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。 如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。 不同的算法可能用不同的时间、空间或效率来完成同样的任务。 一个算法的优劣可以用空间复杂度与时间复杂度来衡量。 算法中的指令描述的是一个计算,当其运行时能从一个初始状态和(可能为空的)初始输入开始,经过一系列有限而清晰定义的状态,最终产生输出并停止于一个终态。 一个状态到另一个状态的转移不一定是确定的。随机化算法在内的一些算法,包含了一些随机输入。 1.1特征 一个算法应该具有以下五个重要的特征: 有穷性 (Finiteness) 算法的有穷性是指算法必须能在执行有限个步骤之后终止; 确切性 (Definiteness) 算法的每一步骤必须有确切的定义; 输入项 (Input) 一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法本身定出了初始条件; 输出项 (Output) 一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的; 可行性 (Effectiveness) 算法中执行的任何计算步骤都是可以被分解为基本的可执行的操作步

动态规划-TSP问题-最短超级串

为君一笑 提交于 2020-03-04 00:35:39
2020-03-03 22:55:08 问题描述: 给定一个字符串数组 A,找到以 A 中每个字符串作为子字符串的最短字符串。 我们可以假设 A 中没有字符串是 A 中另一个字符串的子字符串。 示例 1: 输入:["alex","loves","leetcode"] 输出:"alexlovesleetcode" 解释:"alex","loves","leetcode" 的所有排列都会被接受。 示例 2: 输入:["catg","ctaagt","gcta","ttca","atgcatc"] 输出:"gctaagttcatgcatc" 提示: 1 <= A.length <= 12 1 <= A[i].length <= 20 问题求解: 解法一 :暴力求解 首先我们要明确的就是,本题可以转化成图论的题目,就是在一个图中要遍历所有的节点一次,最后路径的最小值是多少。(这里和TSP略有不同,即我们不需要返回起始节点) 暴力求解,可以理解为全排列,只不过我们做了一些剪枝操作进行了加速。 时间复杂度:O(n!) int res = (int)1e9; List<Integer> path; int n; public String shortestSuperstring(String[] A) { n = A.length; int[][] graph = new int[n][n];