动态规划

贪心算法和动态规划算法

Deadly 提交于 2020-01-23 13:30:25
动态规划和贪心算法都是一种递推算法 即均由局部最优解来推导全局最优解 ( 不从整体最优解出发来考虑, 总是做出在当前看来最好的选择。) 不同点: 贪心算法 与动态规划的区别: 贪心算法中,作出的每步贪心决策都无法改变,由上一步的最优解推导下一步的最优解,所以上一部之前的最优解则不作保留。 能使用贪心法求解的条件 :是否能找出一个贪心标准。我们看一个找币的例子,如果一个货币系统有三种币值,面值分别为一角、五分和一分,求最小找币数时,可以用贪心法求解;如果将这三种币值改为一角一分、五分和一分,就不能使用贪心法求解。 例:贪心法标准的选择 设有n个正整数,将它们连接成一排,组成一个最大的多位整数。 例如:n=3时,3个整数13,312,343,连成的最大整数为34331213。 又如:n=4时,4个整数7,13,4,246,连成的最大整数为7424613。 输入:n 个数 输出:连成的多位数 算法分析:此题很容易想到使用贪心法,在考试时有很多同学把整数按从大到小的顺序连接起来,测试题目的例子也都符合,但最后测试的结果却不全对。按这种标 准,我们很容易找到反例:12,121应该组成12121而非12112,那么是不是相互包含的时候就从小到大呢?也不一定,如12,123就是 12312而非12123,这种情况就有很多种了。是不是此题不能用贪心法呢? 其实此题可以用贪心法来求解

动态规划:最大连续子序列乘积

谁说胖子不能爱 提交于 2020-01-23 08:10:13
题目描写叙述: 给定一个浮点数序列(可能有正数、0和负数),求出一个最大的连续子序列乘积。 分析:若暴力求解,须要O(n^3)时间,太低效,故使用动态规划。 设 data[i]:第i个数据, dp[i]:以第i个数结尾的连续子序列最大乘积, 若题目要求的是最大连续子序列和,则易确定状态转移方程为: dp[i]=max(data[i],dp[i-1]+data[i])(dp[i]为以第i个数结尾的连续子序列最大和) 但乘积存在负负得正的问题,即原本非常小的负数成了一个负数反而变大了。(负数逆袭了), 故不能照抄加法的 转移方程,为了解决问题。须要定义两个数组: dp1[i]:以第i个数结尾的连续子序列最大乘积 dp2[i]:以第i个数结尾的连续子序列最小乘积 转移方程: dp1[i]=max(data[i],dp1[i-1]*data[i],dp2[i-1]*data[i]); dp2[i]=min(data[i],dp1[i-1]*data[i],dp2[i-1]*data[i]); 最后遍历dp1得到最大值即为答案。 代码例如以下: #include<stdio.h> double max(double a,double b){return a>b?a:b;} double min(double a,double b){return a<b?a:b;} double dp1

动态规划(免费馅饼)

倾然丶 夕夏残阳落幕 提交于 2020-01-22 22:37:28
都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼。说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内。馅饼如果掉在了地上当然就不能吃了,所以gameboy马上卸下身上的背包去接。但由于小径两侧都不能站人,所以他只能在小径上接。由于gameboy平时老呆在房间里玩游戏,虽然在游戏中是个身手敏捷的高手,但在现实中运动神经特别迟钝,每秒种只有在移动不超过一米的范围内接住坠落的馅饼。现在给这条小径如图标上坐标: 为了使问题简化,假设在接下来的一段时间里,馅饼都掉落在0-10这11个位置。开始时gameboy站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的馅饼。问gameboy最多可能接到多少个馅饼?(假设他的背包可以容纳无穷多个馅饼) Input 输入数据有多组。每组数据的第一行为以正整数n(0<n<100000),表示有n个馅饼掉在这条小径上。在结下来的n行中,每行有两个整数x,T(0<T<100000),表示在第T秒有一个馅饼掉在x点上。同一秒钟在同一点上可能掉下多个馅饼。n=0时输入结束。 Output 每一组输入数据对应一行输出。输出一个整数m,表示gameboy最多可能接到m个馅饼。 提示:本题的输入数据量比较大,建议用scanf读入,用cin可能会超时。 Sample

核心算法基础一:动态规划

纵饮孤独 提交于 2020-01-22 19:42:37
文章目录 前言 动态规划入门须知 动态规划解决哪一类问题 那些问题适合用该算法思想去解决 动态规划的套路解决步骤 **1. 建立状态转移方程** **2. 缓存并复用以往结果** **3. 按顺序从小往大算** 例题一(easy入门) 1.简单递归(反例) 2. 动态规划 例题二(稍微困难--深入理解) 思路 具体代码 例题三:难度适中(笔试难度) 思路(回溯算法也可以,之后会有解释) 具体代码(个人,不代表标准) 算法总结(套路) 前言 接下来最为核心的知识点目前杨某人思路清晰的整理好了,首先为大家展示几个核心算法的理论思想,只有掌握了这种基础才能更好的做题通过笔试锻炼面试时技术的询问,接下来会给大家一些质量比较高的笔试试题,帮助大家更好的理解算法的思想,完成理论到实践、逻辑到技术的转变,最后会为大家整理一些大厂关注的一些算法试题的套路和应对的套路,不保证百分之百,但是会保证60%以上的思想,话不多说,开始啦~~ 额,多说一句:关于之前的项目和之后的一些比较重要的算法(整理了个人的最好的资源更容易学习和联系)都将会设置上一定的权限,望大家理解,不过粉丝可以一直免费观看 动态规划入门须知 本人掌握动态规划的过程,有点钻牛角尖,这里用我的心历路程给各位同学们做个提醒。当我刚看到动态规划这个响亮的大名时,瞬间陷入了沉思,脑中浮想联翩,揣摩着这个算法应该很带感。 看一些大众的百度的解释:

[Leetcode]647.Palindromic Substrings

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-22 09:23:49
链接: LeetCode647 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。 具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串。 示例 1: 输入: "abc" 输出: 3 解释: 三个回文子串: "a", "b", "c". 示例 2: 输入: "aaa" 输出: 6 说明: 6个回文子串: "a", "a", "a", "aa", "aa", "aaa". 相关标签: 动态规划 一道明显的动态规划题。令dp[i][j]表示字符串索引i-j是否能组成回文,一共有三种情况: 当i==j,此时为单个字符,必成回文 当i==j-1,此时为两个字符,只需要判断这两个是否相同即可 其他,此时采用动态规划,dp[i][j] = dp[i+1][j-1] & (s[i] == s[j]) 代码如下: python: class Solution: def countSubstrings(self, s: str) -> int: res = 0 if not s: return res n = len(s) dp = [[False for j in range(n)] for i in range(n)] for i in reversed(range(n)): for j in range(i,n): if i == j: dp[i][j]

动态规划

喜夏-厌秋 提交于 2020-01-22 05:42:04
导语 动态规划作为一门强有力的编程技术,一直以来在解编程题中都是利器。总感觉自己学习的时候总是学习几道题目,并没有深入理解。故打算做个动态规划专题,包括理论和题目解析。正好在学习《运筹学教程》,里面对运筹学的数学原理知识讲解较为透彻。再结合之前在算法中学习的知识,打算对动态规划做个专题总结。这是我在博客园上的第一篇博客,自己得坚持下去。 动态规划简介 动态规划是解决多阶段决策过程最优化的一种方法。该方法由美国科学家贝尔曼(R Bellman)等人在20世纪50年代初提出。多阶段决策过程,本意指这样一类特殊活动过程,可以按时间顺序分解成相互联系的阶段,称为“时段”,在每一个时段都要做出决策,全部过程的决策是一个决策序列。多阶段决策过程最优化目标是要达到整个活动过程的总体效果最优。 基本概念 1.阶段 按时间或者空间特征分解成若干相互联系的阶段,以便按次序求解每阶段,常用\(k\)表示阶段变量 2.状态 各阶段开始时的客观条件叫做状态。描述各阶段状态的变量称为状态变量,常用\(s_{k}\)表示第\(k\)阶段的状态变量,状态变量\(s_{k}\)的取值范围称为状态集合,用\(S_{k}\)表示。 3.决策和策略 各阶段的状态取定以后,就可以做出不同的决策,从而确定下一阶段的状态,这种决定称之为决策。表示决策的变量,称之为决策变量,常用\(u_k(s_k)\)表示第\(k\

贪心策略+暴力递归+动态规划

跟風遠走 提交于 2020-01-21 00:04:47
贪心策略+暴力递归+动态规划 切金条问题 项目资金最大化问题 会议室占用 介绍递归 动态规划 (from左神算法初级班第七节) 1.切金条问题 【问题】一块金条切成两半,是需要花费和长度数值一样的铜板的。比如 长度为20的 金条,不管切成长度多大的两半,都要花费20个铜 板。一群人想整分整块金条,怎么分最省铜板? 例:给定数组{10,20,30},代表一共三个人,整块金条长度为10+20+30=60,金条要分成10,20,30三个部分。如果,先把长度60的金条分成10和50,花费60 再把长度50的金条分成20和30,花费50 一共花费110铜板。但是如果,先把长度60的金条分成30和30,花费60再把长度30金条分成10和20,花费30一共花费90铜板。 1)哈夫曼编码问题 生成树的非叶节点之和代价最小 2)方法: 每次将数组放入到小跟堆中,每次取出两个堆顶的值(都是最小值),不放回 将两个值相加然后再放入到数组中,直到数组最后剩下最后一个数,就是生成哈夫曼树的代价。 3)代码 public static int lessMoney ( int [ ] arr ) { PriorityQueue < Integer > pQ = new PriorityQueue < > ( ) ; for ( int i = 0 ; i < arr . length ; i ++ ) { pQ

#动态规划 LeetCode 198 打家劫舍

僤鯓⒐⒋嵵緔 提交于 2020-01-20 18:21:05
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统, 如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。 给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下, 能够偷窃到的最高金额。 示例 1: 输入: [1,2,3,1] 输出: 4 解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。 偷窃到的最高金额 = 1 + 3 = 4 。 示例 2: 输入: [2,7,9,3,1] 输出: 12 解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。 偷窃到的最高金额 = 2 + 9 + 1 = 12 。思路: 还是自顶向下分析,首先明确函数的定义,就是要求[0,n-1]范围内最大可能。 以上问题分别可以分解为子问题:分别确定偷取0~n-1,其中最多的哪一种可能。 状态转移方程为F(n) = Max(vi+F(i+2)) class Solution { public int rob(int[] nums) { int n = nums.length; if(n == 0) return 0; int[] res = new int[n]; res[n-1] = nums[n-1

manacher算法(最长回文串)

瘦欲@ 提交于 2020-01-20 16:56:45
题目解释: 子串:小于等于原字符串长度由原字符串中任意个连续字符组成的子序列 回文:关于中间字符对称的文法,即“aba”(单核)、“cabbac”(双核)等 最长回文子串:1.寻找回文子串;2.该子串是回文子串中长度最长的。 以上原作者:胥临轩链接:https://www.zhihu.com/question/37289584/answer/370848679 首先要知道这个算法是用来在O(n)的时间里看一个字符串的最长回文子串的长度是什么。其次,它的核心原理还是动态规划。 既然是动态规划,那么一定要找子状态!这一点很重要。几乎所有的动态规划,你明白子状态是什么,子状态是如何组成下一个状态的,就等于搞清楚这个算法。 那么我们先来这样看,假如我们知道一个数组p,p[n]代表的是从n这个位置为中心的子串,它的右边一半的长度,换句话说:2*p[n]是以n处为中心的回文子串的长度。 这里注意这个p[n]包括了一开始加进去的 #,所以实际上去掉 # 后的回文串长度就是p[n],不需要乘2了。 那么根据动态规划的定义,要求这么一个数组,就是如下的方法, 如果要求p[i],那么我们一定已经知道了小于i的所有值(也就是说如果j<i,那么p[j]一定知道了,并且是个不会再变的值),而且,还要利用之前的p[j]去求p[i]。那么如何设计这个算法呢? 你必须首先知道如何用p[j]来求p[i]

动态规划和贪心算法的区别

£可爱£侵袭症+ 提交于 2020-01-20 16:18:58
这是转别人的,待会我会自己总结 动态规划和贪心算法的区别 动态规划和贪心算法都是一种递推算法 均有局部最优解来推导全局最优解 不同点: 贪心算法: 1.贪心算法中,作出的每步贪心决策都无法改变,因为贪心策略是由上一步的最优解推导下一步的最优解,而上一部之前的最优解则不作保留。 2.由(1)中的介绍,可以知道贪心法正确的条件是:每一步的最优解一定包含上一步的最优解。 动态规划算法: 1.全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解,因此需要记录之前的所有最优解 2.动态规划的关键是状态转移方程,即如何由以求出的局部最优解来推导全局最优解 3.边界条件:即最简单的,可以直接得出的局部最优解 ============================================================================== 来源: https://www.cnblogs.com/nwpuzzh/p/3926049.html