整除15问题 贪心算法

合集下载

列举用贪心算法求解的经典问题

列举用贪心算法求解的经典问题

列举用贪心算法求解的经典问题贪心算法是一种简单而高效的问题求解方法,通常用于求解最优化问题。

它通过每一步选择当前状态下的最优解,最终得到全局最优解。

贪心算法的核心思想是:每一步都做出一个局部最优的选择,并认为这个选择一定可以达到全局最优。

以下是一些经典问题,可以用贪心算法求解:1. 零钱兑换问题(Coin Change Problem):给定一些不同面额的硬币和一个目标金额,找到最少的硬币数量,使得硬币总额等于目标金额。

贪心算法可以按照硬币的面额从大到小进行选择,每次选择尽量大面额的硬币。

2. 区间调度问题(Interval Scheduling Problem):给定一些区间,找到最多的不相交区间。

贪心算法可以按照区间的结束时间进行排序,每次选择结束时间最早的区间,确保选择的区间不重叠。

3. 分糖果问题(Candy Problem):给定一个数组表示每个孩子的评分,要求给这些孩子分糖果,满足以下要求:每个孩子至少分到一个糖果,评分高的孩子要比相邻孩子分到的糖果多。

贪心算法可以从左到右进行两次遍历,分别处理评分递增和评分递减的情况。

4. 跳跃游戏问题(Jump Game Problem):给定一个非负整数数组,表示每个位置的最大跳跃长度,判断是否能从第一个位置跳到最后一个位置。

贪心算法可以记录当前能够到达的最远位置,并且更新为更远的位置。

5. 任务调度器问题(Task Scheduler Problem):给定一串任务,每个任务需要一定的冷却时间,要求以最短的时间完成所有任务。

贪心算法可以按照出现次数进行排序,优先执行出现次数最多的任务,并在冷却时间内执行其他任务。

6. 区间覆盖问题(Interval Covering Problem):给定一些区间,找到最少的区间数,使得它们的并集覆盖了所有输入区间。

贪心算法可以根据区间的起始位置进行排序,每次选择最早结束的区间,并将它添加到最终结果中。

以上仅是一些经典问题的例子,实际上还有很多问题可以用贪心算法来求解。

贪心算法程序设计

贪心算法程序设计

贪心算法程序设计贪心算法程序设计1. 什么是贪心算法贪心算法(Greedy Algorithm)是一种常见的算法思想,它在每一步选择中都采取当前状态下的最优选择,从而希望最终达到全局最优解。

贪心算法的核心思想是局部最优解能导致全局最优解。

2. 贪心算法的基本步骤贪心算法的基本步骤如下:1. 定义问题的优化目标。

2. 将问题分解成子问题。

3. 选择当前最优的子问题解,将子问题的解合并成原问题的解。

4. 检查是否达到了问题的优化目标,如果没有达到,则回到第二步,继续寻找下一个最优子问题解。

5. 在所有子问题解合并成原问题解后,得到问题的最优解。

3. 贪心算法的应用场景贪心算法的应用非常广泛,几乎可以用于解决各种优化问题。

以下几个常见的应用场景:1. 零钱找零问题:给定一定面额的纸币和硬币,如何找零使得所需纸币和硬币的数量最小?2. 区间调度问题:给定一些活动的开始时间和结束时间,如何安排活动使得可以办理的活动数量最大?3. 背包问题:给定一些具有重量和价值的物品,如何选择物品使得背包的总价值最大?4. 最小树问题:给定一个带权无向图,如何找到一棵树,使得它的边权之和最小?5. 哈夫曼编码问题:给定一组字符和相应的频率,如何构造一个满足最低编码长度限制的二进制编码?4. 贪心算法的优缺点贪心算法的优点是简单、高效,可以快速得到一个近似最优解。

而且对于一些问题,贪心算法能够得到全局最优解。

贪心算法的缺点在于它不一定能够得到全局最优解,因为在每一步只考虑局部最优解,无法回溯到之前的选择。

5. 贪心算法的程序设计在使用贪心算法进行程序设计时,通常需要以下几个步骤:1. 定义问题的优化目标。

2. 将问题分解成子问题,并设计子问题的解决方案。

3. 设计贪心选择策略,选择局部最优解。

4. 设计贪心算法的递推或迭代公式。

5. 判断贪心算法是否能够得到全局最优解。

6. 编写程序实现贪心算法。

6.贪心算法是一种常见的算法思想,它在每一步选择中都采取当前状态下的最优选择,从而希望最终达到全局最优解。

贪心算法求解最优解问题

贪心算法求解最优解问题

贪心算法求解最优解问题贪心算法是计算机科学领域中常用的一种算法。

它常常被用来求解最优解问题,如背包问题、最小生成树问题、最短路径问题等。

贪心算法解决最优解问题的基本思路是,每一步都选取当前状态下最优的解决方案,直到达到全局最优解。

在这篇文章中,我们将为大家深入探讨贪心算法求解最优解问题的基本思路、算法复杂度和应用场景等方面的知识。

基本思路贪心算法是一种基于贪心策略的算法。

其核心思想是,每一步都采用当前最优策略,以期最终达到全局最优解。

在贪心算法中,每个子问题的最优解一般都是由上一个子问题的最优解推导出来的。

因此,关键在于如何找到最优解。

具体而言,贪心算法一般由三部分组成,分别为:状态、选择和判断。

首先,需要明确当前问题的状态,即问题的规模和限制条件。

然后,在当前的限制条件下,我们需要从可能的方案中选择出最优的方案,并把这个选择作为解的一部分。

最后,需要判断选择是否符合问题的限制条件,是否达到全局最优解。

算法复杂度在进行算法分析时,我们需要考虑算法的时间复杂度和空间复杂度。

对于贪心算法而言,其时间复杂度一般是 O(nlogn) 或 O(n) 级别的,其中 n 表示问题的规模。

这种效率在实际应用中表现出了很高的稳定性和效率。

应用场景贪心算法通常应用于需要求解最优解问题的场景中。

例如:- 贪心算法可以用来求解背包问题。

在背包问题中,我们需要在限定的空间内选取最有价值的物品装入背包中以努力获得最大的收益。

在贪心策略下,我们只需要按单位重量价值从大到小的顺序进行选择,就可以得到最优解;- 贪心算法也可以用来求解最小生成树问题。

这个问题是指,在给定一个图的时候,我们需要选出一棵生成树,使得生成树上的所有边权之和最小。

在此问题中,我们可以将图上的边权按大小排序,然后顺序选择边直至生成树。

这样,我们可以得到与全局最优解很接近的解;- 贪心算法还可以用来求解最短路径问题。

在最短路径问题中,我们需要找到从一个节点到另一个节点的最短路径。

贪心算法经典例题

贪心算法经典例题

贪心算法经典例题引言贪心算法是一种常见的算法策略,它在求解问题时每一步都选择当前状态下的最优解,从而最终得到全局最优解。

本文将介绍一些经典的贪心算法例题,帮助读者更好地理解贪心算法的思想和应用。

背景知识在讨论贪心算法之前,我们先了解一些背景知识。

1. 贪心算法的特点贪心算法具有以下特点: - 每一步都选择当前状态下的最优解; - 不进行回溯;- 不保证能得到全局最优解,但通常能得到较优解; - 算法运行效率高。

2. 贪心算法的适用情况贪心算法适用于满足以下条件的问题: - 具有最优子结构性质:问题的最优解包含子问题的最优解; - 贪心选择性质:局部最优解能导致全局最优解; - 没有后效性:当前的选择不会影响后续的选择。

经典例题1:找零钱问题问题描述假设有1元、5元、10元、20元、50元、100元面值的纸币,如何用最少的纸币数量找零给顾客?对于找零问题,贪心算法可以得到最优解。

具体步骤如下: 1. 首先,我们选择最大面额的纸币进行找零。

2. 然后,将选择的纸币数量减去顾客需找的金额,得到剩余金额。

3. 重复步骤1和步骤2,直到剩余金额为0。

实现代码int[] denominations = {100, 50, 20, 10, 5, 1};int[] counts = new int[denominations.length];int amount = 168;for (int i = 0; i < denominations.length; i++) {counts[i] = amount / denominations[i];amount %= denominations[i];}System.out.println("找零纸币面额及数量:");for (int i = 0; i < denominations.length; i++) {if (counts[i] > 0) {System.out.println(denominations[i] + "元:" + counts[i] + "张");}}分析与总结通过贪心算法,我们可以得到找零纸币的最优解。

贪心算法模板

贪心算法模板

贪心算法(Greedy Algorithm)是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。

贪心算法并不总是得到问题的最优解,但对许多问题它能产生整体最优解或整体最优解的近似解。

下面是一个简单的贪心算法模板,用于解决一些优化问题:pythondef greedy_algorithm(input_data):# 初始化结果变量result = []# 根据输入数据的特性进行排序或预处理sorted_data = sort_or_preprocess(input_data)# 遍历排序后的数据for item in sorted_data:# 检查是否满足某个条件,例如是否可以选择该元素if can_choose(item, result):# 如果满足条件,则选择该元素并更新结果result.append(item)# 可能还需要执行一些额外的操作,例如更新状态或计数器update_state(result, item)return result# 根据具体问题的需要,实现排序或预处理函数def sort_or_preprocess(input_data):# 对输入数据进行排序或预处理pass# 根据具体问题的需要,实现选择条件函数def can_choose(item, result):# 检查是否可以选择该元素pass# 根据具体问题的需要,实现状态更新函数def update_state(result, item):# 更新状态或计数器pass请注意,这只是一个通用的贪心算法模板,具体实现会根据问题的不同而有所变化。

在实际应用中,你需要根据问题的特点来设计合适的排序、选择和状态更新策略。

同时,也需要验证贪心策略是否能够得到全局最优解,或者是否能够得到满意的近似解。

1。

贪心算法经典例题

贪心算法经典例题

贪心算法经典例题所谓贪心算法指的是为了解决在不回溯的前提之下,找出整体最优或者接近最优解的这样一种类型的问题而设计出来的算法。

贪心算法的基本思想是找出整体当中每个小的局部的最优解,并且将所有的这些局部最优解合起来形成整体上的一个最优解。

因此能够使用贪心算法的问题必须满足下面的两个性质:1.整体的最优解可以通过局部的最优解来求出;2.一个整体能够被分为多个局部,并且这些局部都能够求出最优解。

使用贪心算法当中的两个典型问题是活动安排问题和背包问题。

利用贪心算法解题,需要解决两个问题:一是问题是否适合用贪心法求解。

我们看一个找币的例子,如果一个货币系统有3种币值,面值分别为一角、五分和一分,求最小找币数时,可以用贪心法求解;如果将这三种币值改为一角一分、五分和一分,就不能使用贪心法求解。

用贪心法解题很方便,但它的适用范围很小,判断一个问题是否适合用贪心法求解,目前还没有一个通用的方法,在信息学竞赛中,需要凭个人的经验来判断何时该使用贪心算法。

二是确定了可以用贪心算法之后,如何选择一个贪心标准,才能保证得到问题的最优解。

在选择贪心标准时,我们要对所选的贪心标准进行验证才能使用,不要被表面上看似正确的贪心标准所迷惑,如下面的例子。

例2 (NOIP1998tg)设有n个正整数,将他们连接成一排,组成一个最大的多位整数。

例如:n=3时,3个整数13,312,343,连成的最大整数为:34331213又如:n=4时,4个整数7,13,4,246连接成的最大整数为7424613 输入:NN个数输出:连接成的多位数算法分析:此题很容易想到使用贪心法,在考试时有很多同学把整数按从大到小的顺序连接起来,测试题目的例子也都符合,但最后测试的结果却不全对。

按这种贪心标准,我们很容易找到反例:12,121 应该组成12121而非12112,那么是不是相互包含的时候就从小到大呢?也不一定,如:12,123 就是12312而非12112,这样情况就有很多种了。

贪心算法经典例题

贪心算法经典例题

贪心算法经典例题贪心算法是一种求解最优问题的算法思想,其核心理念是每一步都选择当前最优的策略,从而达到全局最优解。

贪心算法可以应用于许多经典问题,下面将介绍几个常见的贪心算法经典例题及相关参考内容。

1. 会议室安排问题题目描述:给定一组会议的开始时间和结束时间,求解如何安排会议,使得尽可能多的会议可以在同一时间段内进行。

解题思路:贪心算法可以通过每次选择结束时间最早的会议来求解。

首先将会议按照结束时间排序,选择第一个会议作为首先安排的会议,然后依次选择后续结束时间不冲突的会议进行安排。

相关参考内容:- 《算法导论》第16章:贪心算法(ISBN: 9787115265955)- 《数据结构与算法分析》第13章:贪心算法(ISBN: 9787302483626)2. 零钱兑换问题题目描述:给定一定面额的硬币,求解如何用最少的硬币数量兑换指定金额的零钱。

解题思路:贪心算法可以通过每次选择面额最大且不超过目标金额的硬币来求解。

从面额最大的硬币开始,尽可能多地选择当前面额的硬币,并减去已经选择的硬币金额,直到金额为0。

相关参考内容:- 《算法导论》第16章:贪心算法(ISBN: 9787115265955)- 《算法4》第1章:基础(ISBN: 9787302444627)3. 区间调度问题题目描述:给定一组区间,求解如何选择尽可能多的不重叠区间。

解题思路:贪心算法可以通过每次选择结束时间最早的区间来求解。

首先将区间按照结束时间排序,选择第一个区间作为首先选择的区间,然后依次选择后续结束时间不与已经选择的区间重叠的区间进行选择。

相关参考内容:- 《算法导论》第16章:贪心算法(ISBN: 9787115265955)- 《数据结构与算法分析》第13章:贪心算法(ISBN: 9787302483626)4. 分糖果问题题目描述:给定一组孩子和一组糖果,求解如何分配糖果,使得最多的孩子能够得到满足。

解题思路:贪心算法可以通过每次选择糖果最小且能满足当前孩子的糖果来求解。

简述贪心算法的一般解题步骤

简述贪心算法的一般解题步骤

简述贪心算法的一般解题步骤一、基本步骤,贪心算法的一般解题步骤二、局部搜索算法。

在已知区域内设置一定数量的门槛值,初始化时,从每个门限值开始,沿着所有的可能走向探求一条满足要求的最佳路径,然后把这条最佳路径作为整个搜索区域的一部分进行搜索。

三、连续搜索算法。

进入每一个边界,从每一个可能的出口出发,按照边界上已经设置好的各种开关进行多次尝试,直到找到某种方案为止,该方案就是该边界的一种最优解。

其他可以通过边界信息调整变化的可能路径称为其他可选路径。

算法1:(1)将被测空间分成互不相交的四个区域。

(2)每个子集A与B分别设为当前搜索的出发点和回到点,即A={-1};B={1}。

(3)根据所需解决的问题及性质,确定应使用的门限值的数目。

(4)将第(3)条中的{-1}、{1}设为给定的初始门限值。

(5)假定只有当N=N0时才停止进行下一步,则有m=1, 2,…, N(6)采用多重线性搜索或递归算法寻找P(N|M)=N*M的解。

4.提取有用的最大元素。

由有用的最大元素作为最优决策边界的一部分。

通常用给定的数目(N)提取有用的最大元素,然后按照各子边界上有用的最大元素数目提取更多的有用最大元素。

(7)修改并检验各边界的决策。

用初始门限值(0)、(1)、(2)、(3)对各边界加权计算它们的平均有用的最大元素;利用累积的结果来估计各个边界的实际决策值。

(8)返回决策边界。

(9)执行下一步。

(10)反复执行,直至遇到阻碍为止。

5.由有用的最大元素作为最优决策边界。

(11)再做一次加权平均运算,得到新的决策边界,如此继续循环下去,直至达到预期的终点。

(12)判断总体性能。

根据最小费用原理和不等式约束条件,求出各个子边界的决策值之和是否等于母边界的决策值。

若是,说明此方案比较适合(当前)状态;否则需要重新制定决策。

列举用贪心算法求解的经典问题

列举用贪心算法求解的经典问题

列举用贪心算法求解的经典问题
1. 零钱兑换问题:给定一些面值不同的硬币和一个金额,要求用最少的硬币凑出这个金额。

2. 最小生成树问题:给定一个无向带权图,要求用最小的权值构建一棵生成树。

3. 背包问题:给定一些物品和一个背包,每个物品有对应的价值和重量,要求在背包容量限制下,选取物品使得总价值最大。

4. 活动安排问题:有若干个活动需要分配一段时间,每个活动有对应的开始时间和结束时间,要求选取尽可能多的活动,使得任两个安排的活动时间不重叠。

5. 单源最短路径问题:给定一个有向带权图和一个起始节点,要求求出从起始节点到其他所有节点的最短路径。

6. 任务调度问题:有若干个需要完成的任务和多个可执行任务的处理器,要求将任务分配给处理器,使得执行总时间最小。

7. 区间覆盖问题:给定一些区间,要求用尽可能少的区间覆盖整个线段。

8. 哈夫曼编码问题:给定一些字符及其对应的出现概率,要求用最短的编码方式表示这些字符。

贪心算法一般解题步骤

贪心算法一般解题步骤

贪心算法一般解题步骤
贪心算法是一种在求解最优解时,每次都选择当前最优解的算法。

它的基本思想是:每一步都选择当前最优的解,最终得到的解就是最优解。

贪心算法的优点是简单易懂,实现起来也比较容易,但是它的缺点是不一定能得到最优解。

贪心算法一般解题步骤如下:
1、确定问题的最优解:首先要确定问题的最优解,即最终要求的最优解。

2、确定贪心策略:根据问题的最优解,确定贪心策略,即每一步都选择当前最优解。

3、实施贪心策略:根据贪心策略,每一步都选择当前最优解,最终得到的解就是最优解。

4、检验最优解:最后,要检验最优解是否正确,如果正确,则说明贪心算法得到的解是最优解;如果不正确,则说明贪心算法得到的解不是最优解。

贪心算法是一种在求解最优解时,每次都选择当前最优解的算法,它的优点是简单易懂,实现起来也比较容易,但是它的缺点是不一定能得到最优解。

贪心算法一般解题步骤是:首先要确定问题的最优解,然后根据问题的最优解确定贪心策略,接着根据贪心策略每一步都选择当前最优解,最后检验最优解是否正确。

贪心算法在许多场景中都有应用,比如资源分配、路径规划、排序等。

它的优点是简单易懂,实现起来也比较容易,但是它的缺点是不一定能得到最优解,因此在实际应用中,要根据实际情况来选择合适的算法。

贪心算法总结

贪心算法总结

贪⼼算法总结简介贪⼼算法(英⽂:greedy algorithm),是⽤计算机来模拟⼀个“贪⼼”的⼈做出决策的过程。

这个⼈⼗分贪婪,每⼀步⾏动总是按某种指标选取最优的操作。

⽽且他⽬光短浅,总是只看眼前,并不考虑以后可能造成的影响。

可想⽽知,并不是所有的时候贪⼼法都能获得最优解,所以⼀般使⽤贪⼼法的时候,都要确保⾃⼰能证明其正确性。

本⽂主要介绍,在解决诸多贪⼼算法的问题之后的⼼得。

常⽤场景最常见的贪⼼算法分为两种。

「我们将 XXX 按照某某顺序排序,然后按某种顺序(例如从⼩到⼤)选择。

」。

「我们每次都取 XXX 中最⼤/⼩的东西,并更新 XXX。

」(有时「XXX 中最⼤/⼩的东西」可以优化,⽐如⽤优先队列维护)第⼀种是离线的,先处理后选择,第⼆种是在线的,边处理边选择。

常见的出题背景为:确定某种最优组合(硬币问题)区间问题(合理安排区间)字典序问题最值问题A最优组合硬币问题是贪⼼算法⾮常经典的题⽬,关于最优组合问题,我认为主要分为两种类型:简单 -- 直接排序之后按照某种策略选取即可复杂 -- 除了按照贪⼼策略外,还需要进⾏某些处理或者模拟硬币问题硬币问题有1元、5元、10元、50元、100元、500元的硬币各C1、C5、C10、C50、C100、C500枚。

现在要⽤这些硬币来⽀付A元,最少需要多少枚硬币?假设本题⾄少存在⼀种⽀付⽅法。

0≤C1、C5、C10、C50、C100、C500≤1090≤A≤109本题是上述说的简单类型的题⽬,简⽽⾔之要使得硬币最少,则优先使⽤⼤⾯额的硬币。

因此本题的解法便⾮常清晰了,只需要从后往前遍历⼀遍即可(默认为硬币已经按⾯额⼤⼩进⾏排序)const int V[6] = {1, 5, 10, 50, 100, 500};int A, C[6]; // inputvoid solve(){int ans(0);for (int i = 5; i >= 0; -- i){int t = min(A / V[i], C[i]);A -= t * V[i];ans += t;}cout << ans << '\n';}零花钱问题POJ3040 AllowanceDescriptionAs a reward for record milk production, Farmer John has decided to start paying Bessie the cow a small weekly allowance. FJ has a set of coins in N (1 <= N <= 20) different denominations, where each denomination of coin evenly divides the next-larger denomination (e.g., 1 cent coins, 5 cent coins, 10 cent coins, and 50 cent coins).Using the given set of coins, he would like topay Bessie at least some given amount of money C (1 <= C <= 100,000,000) every week.Please help him ompute the maximum number of weeks he can pay Bessie.Input* Line 1: Two space-separated integers: N and C* Lines 2..N+1: Each line corresponds to a denomination of coin and contains two integers: the value V (1 <= V <= 100,000,000) of the denomination, and the number of coins B (1 <= B <= 1,000,000) of this denomation in Farmer John's possession.Output* Line 1: A single integer that is the number of weeks Farmer John can pay Bessie at least C allowanceSample Input3 610 11 1005 120Sample Output111这题的题⽬⼤意是:农场主每天都要给贝西⾄少为C的津贴。

删数问题贪心算法实验总结

删数问题贪心算法实验总结

删数问题贪心算法实验总结
一、问题背景
在计算机科学中,删数问题是指给定一个正整数序列,每次可以删除
其中两个相邻的数字,并将它们的和作为新的数字插入到原序列中。

这个过程不断重复,直到序列中只剩下一个数字为止。

删数问题最初
由 Josephus 提出,因此也被称为 Josephus 问题。

二、贪心算法
贪心算法是一种基于贪心思想的算法,在每一步选择中都采取当前状
态下最好或最优的选择,从而希望导致结果是全局最好或最优的算法。

贪心算法通常需要证明其正确性。

三、实验设计
本次实验旨在探究删数问题中使用贪心算法得出结果的正确性。

实验
分为以下步骤:
1. 编写程序模拟删数过程,并使用随机生成的数据进行测试。

2. 编写程序实现贪心算法解决删数问题。

3. 对比模拟和贪心算法得出的结果,并分析其正确性。

4. 利用大量数据测试贪心算法的时间复杂度。

四、实验结果
经过多次测试,模拟和贪心算法得出的结果完全一致,证明了贪心算法在解决删数问题时具有正确性。

同时,通过大量数据测试,贪心算法的时间复杂度远远小于模拟算法,证明了贪心算法在解决删数问题时具有高效性。

五、结论
本次实验证明了贪心算法在解决删数问题时具有正确性和高效性。

在实际应用中,可以采用贪心算法来快速求解删数问题。

同时,本次实验也提醒我们,在使用贪心算法时需要对其正确性进行证明,并且需要注意不同情况下的最优选择可能不同。

整除15问题 贪心算法算法设计 C++

整除15问题 贪心算法算法设计 C++
a[i].bFra bibliotek = true;
flag = i;
break;
}
}
if(flag>0){
find(len);
}
else{
for(int j = len;j>0;j--){
if(a[j].rest == 1&&a[j].bo == false){
代码实现:
#include"iostream"
#include"cstring"
#include"cstdio"
using namespace std;
#define N 10
typedef struct{
int x;
bool bo; //记住此数是否已用
int rest; //记住该数除3的余数
}
else{
for(int j = len;j>0;j--){
if(a[j].rest == 2&&a[j].bo == false){
++flag;
a[j].bo = true;
if(flag == 1)
break;
}
for(int i = len;i>0;i--){
if(a[i].rest == 1&&a[i].bo == false){
a[i].bo = true;
flag = i;
break;
}
}
if(flag>0){
find(len);
将构建出的最大整数输出。

【精选】贪心算法

【精选】贪心算法

【精选】贪心算法贪心算法近年来的信息学竞赛中,经常需要求一个问题的可行解和最优解,这就是所谓的最优化问题。

贪心法是求解这类问题的一种常用算法。

在众多的算法中,贪心法可以算的上是最接近人们日常思维的一种算法,他在各级各类信息学竞赛、尤其在一些数据规模很大的问题求解中发挥着越来越重要的作用。

一、什么是贪心法贪心法是从问题的某一个初始状态出发,通过逐步构造最优解的方法向给定的目标前进,并期望通过这种方法产生出一个全局最优解的方法。

做出贪心决策的依据称为贪心准则(策略),但要注意决策一旦做出,就不可再更改。

贪心与递推不同的是,推进的每一步不是依据某一固定的递推式,而是做一个当时看似最佳的贪心选择,不断的将问题实例归纳为更小的相似子问题。

所以,在有些最优化问题中,采用贪心法求解不能保证一定得到最优解,这时我们可以选择其他解决最优化问题的算法,如动态规划等。

归纳、分析、选择贪心准则是正确解决贪心问题的关键。

二、贪心法的特点及其优缺点贪心法主要有以下两个特点:贪心选择性质:算法中每一步选择都是当前看似最佳的选择,这种选择依赖于已做出的选择,但不依赖于未作出的选择。

最优子结构性质:算法中每一次都取得了最优解(即局部最优解),要保证最后的结果最优,则必须满足全局最优解包含局部最优解。

利用贪心法解题的一般步骤是:1、产生问题的一个初始解;2、循环操作,当可以向给定的目标前进时,就根据局部最优策略,向目标前进一步;3、得到问题的最优解(或较优解)。

贪心法的优缺点主要表现在:优点:一个正确的贪心算法拥有很多优点,比如思维复杂度低、代码量小、运行效率高、空间复杂度低等,是信息学竞赛中的一个有力武器,受到广大同学们的青睐。

缺点:贪心法的缺点集中表现在他的“非完美性”。

通常我们很难找到一个简单可行并且保证正确的贪心思路,即使我们找到一个看上去很正确的贪心思路,也需要严格的正确性证明。

这往往给我们直接使用贪心算法带来了巨大的困难。

贪心算法+实例

贪心算法+实例

贪⼼算法+实例贪⼼算法(⼜称贪婪算法)是指,在对时,总是做出在当前看来是最好的选择。

也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部。

(官⽅解释)。

所谓的贪⼼算法主要理解就在这个“贪⼼”上⾯,所谓贪⼼,就是找到最好的,也就是上⾯说的最优解。

我们可以通过各种⽅式找到当前的最优解,将最有解利⽤过后,将其清除,再去找下⼀个最优解。

来⼀个例⼦来说明。

题⽬描述鲁宾逊先⽣有⼀只宠物猴,名叫多多。

这天,他们两个正沿着乡间⼩路散步,突然发现路边的告⽰牌上贴着⼀张⼩⼩的纸条:“欢迎免费品尝我种的花⽣!――熊字”。

鲁宾逊先⽣和多多都很开⼼,因为花⽣正是他们的最爱。

在告⽰牌背后,路边真的有⼀块花⽣⽥,花⽣植株整齐地排列成矩形⽹格(如图111)。

有经验的多多⼀眼就能看出,每棵花⽣植株下的花⽣有多少。

为了训练多多的算术,鲁宾逊先⽣说:“你先找出花⽣最多的植株,去采摘它的花⽣;然后再找出剩下的植株⾥花⽣最多的,去采摘它的花⽣;依此类推,不过你⼀定要在我限定的时间内回到路边。

”我们假定多多在每个单位时间内,可以做下列四件事情中的⼀件:1) 从路边跳到最靠近路边(即第⼀⾏)的某棵花⽣植株;2) 从⼀棵植株跳到前后左右与之相邻的另⼀棵植株;3) 采摘⼀棵植株下的花⽣;4) 从最靠近路边(即第⼀⾏)的某棵花⽣植株跳回路边。

现在给定⼀块花⽣⽥的⼤⼩和花⽣的分布,请问在限定时间内,多多最多可以采到多少个花⽣?注意可能只有部分植株下⾯长有花⽣,假设这些植株下的花⽣个数各不相同。

例如在图2所⽰的花⽣⽥⾥,只有位于(2,5),(3,7),(4,2),(5,4)(2, 5), (3, 7), (4, 2), (5, 4)(2,5),(3,7),(4,2),(5,4)的植株下长有花⽣,个数分别为13,7,15,913, 7, 15, 913,7,15,9。

沿着图⽰的路线,多多在212121个单位时间内,最多可以采到373737个花⽣。

贪心算法例题简单说明

贪心算法例题简单说明

贪⼼算法例题简单说明
1.选择不相交区间问题
贪⼼思路:按照结束时间的顺序排序,结束时间越早,后⾯就能放越多的事。

2.区间选点问题
贪⼼思路:从前往后扫每个区间的树⽊,数⽬的那个区间,从后往前种树。

3.区间覆盖问题
贪⼼思路:预处理完了之后,要找到右端点坐标最⼤的⼀个,直到到边。

这⾥我就要说⼀下了⼀定要注意上下的边界问题:
1.两个圆相切肯定不对,覆盖不全
2.覆盖圆与边相切也不对,覆盖不全
4.流⽔作业调度问题
贪⼼思路:
5.带期限和带罚款的单位时间任务调度
贪⼼思路:罚款越⼤,越要完成,所以罚款⼤的要先处理,将罚款⼤的放在能放区间的最后。

贪心算法

贪心算法

输出: 最长序列的基因序列基因,基因编号从1~N。
该题是典型的最多作业序列问题
7
可以将基因起始点看成一个作业的开 始时间,基因终点看成完成该作业的 终止时间。用这些基因拼出长度最长 的基因序列(连续的基因前一个终点 不能大于等于后一个基因起始点), 相当于求能完成的最多作业序列。
贪心在什么地方?
谁先结束就先选谁。
17
∞ ∞ 0 ∞ ∞ ∞ ∞ ∞ 12 ∞ ∞ ∞∞∞0 ∞∞∞∞ 4∞∞
……
13
从0到各终点的Dist[i]值变化
终点 1 2 3 4 5
从0到各终点的Dist[i]值
i=1 0 0 ∞ ∞ ∞ i=2 0 0 5 7 ∞ i=3 0 0 5 7 ∞ i=4 0 0 5 7 ∞ i=5 0 0 5 7 ∞ 0 0 5 7
从0到各终点的Dist[i]值 i=6 i=7 0 0 5 7 ∞ ∞ ∞ i=8 0 0 5 7 ∞ ∞ ∞ i=9 i=10
∞ ∞ ∞
6 7 8
9 10
∞ ∞ ∞
∞ ∞ 0
∞ ∞ ∞

∞ ∞ 12

∞ ∞ 9

∞ ∞ 9
19
9
19
9
19
9
19
∞ ∞ ∞ ∞ ∞ 21 21 0,1 0,1,2 0,1,2,3 0,1,2,3,4,5,6,7,8,9,10 14 贪心在:下一个要取的Dist[i]最小对应的顶点
贪心在什么地方?
每次取都是取当前权值最小的。
这就是狄克斯特拉(Dijkstra) 算法的主 要思想
15
特别提醒:
贪心算法的典型应用 哈夫曼编码 最小生成树 最短路径 要搞的清清楚楚、明明白白
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

整除15问题
描述
问题描述:
给定一个只包含数字[0..9]的字符串,求使用字符串中的某些字符,构建一个能够整除15的最大的整数。

注意,字符串中的每个字符只能使用一次。

编程任务:
求由给定字符串构建的能够整除15的最大整数。

输入数据为一个只包含数字[0..9]字符串,字符串的长度为1~1000。

Output
将构建出的最大整数输出。

每个输入的数据都放在input.txt文件中,输出的数据都存在output.txt文件中。

如果无法构建出能够整除15的整数,请输出
“impossible”
输入示例输出示例
input.txt output.txt
02041 4200
Hint
从原来的字串中选择出最少最小的数扣除以满足整除3和5的要求。

先考虑从原字串中删除最少而且最小的数使得满足整除3。

有以下几种情况:
情况一:
0,3,6 ,9:除3余0。

不用删除操作。

情况二:
2,5,8:除3余2。

那么只要删除余1的那一类数中最小的一个。

如果没有数串中没有余1的数,就删除两个余2的数。

情况三:
1,4,7:除3余1。

那么只要删除余2的那一类数中最小的一个。

如果没有数串中没有余2的数,就删除两个最小的余1的数。

最后,剩余的数串以最大的并且以满足整除5的要求输出。

在0存在的时候,就按计数的顺序输出即可。

如果在数串中没有0,则必须有个5放在个位。

代码实现:
#include"iostream"
#include"cstring"
#include"cstdio"
using namespace std;
#define N 10
typedef struct{
int x;
bool bo; //记住此数是否已用
int rest; //记住该数除3的余数
}node;
node a[N];
int onefast(int low,int high){ //一次快排int key = a[low].x;
a[0].x = key;
while(low<high){
while(low<high&&a[high].x<=key)
--high;
a[low].x = a[high].x;
while(low<high&&a[low].x>=key)
++low;
a[high].x = a[low].x;
}
a[high].x = a[0].x;
return high;
}
void fsort(int low,int high){ //快速排序if(low<high){
int q = onefast(low,high);
fsort(low,q-1);
fsort(q+1,high);
}
}
void find(int len);
void del(int t,int len){
int flag = -1;
if(t == 1){
for(int i = len;i>0;i--){
if(a[i].rest == 1&&a[i].bo == false){
a[i].bo = true;
flag = i;
break;
}
}
if(flag>0){
find(len);
}
else{
for(int j = len;j>0;j--){
if(a[j].rest == 2&&a[j].bo == false){
++flag;
a[j].bo = true;
if(flag == 1)
break;
}
}
if(flag == 1)
find(len);
else if(flag < 1){
cout<<"impossible"<<endl;
}
}
}
else{
for(int i = len;i>0;i--){
if(a[i].rest == 2&&a[i].bo == false){
a[i].bo = true;
flag = i;
break;
}
}
if(flag>0){
find(len);
}
else{
for(int j = len;j>0;j--){
if(a[j].rest == 1&&a[j].bo == false){
++flag;
a[j].bo = true;
if(flag == 1)
break;
}
}
if(flag == 1)
find(len);
else if(flag < 1){
cout<<"impossible"<<endl;
}
}
}
}
void find(int len){
int flag = -2;
if(a[len].x!=0){ //字符串中没有0 时
for(int i = 1;i<len;i++){
if(a[i].x==5){
flag = i;
break;
}
}
if(flag<0){ //字符串中没有0 且没有5 时。

cout<<"impossible"<<endl;
}
else{ //字符串没有0 ,但有5 时。

a[flag].bo = true;
int sum = 0;
for(int j = 1;j<=len;j++){
if(a[j].bo == false){
sum += a[j].x;
}
}
int t = (sum + 5)%3;
if( t== 0){//找到
for(int k = 1;k<=len;k++){
if(a[k].bo == false)
cout<<a[k].x;
}
cout<<5;
cout<<endl;
}
else{ // 此数不符合时
del(t,len);
}
}
}
else{ //字符串中有0 时
//a[len].bo = true;
int sum = 0;
for(int j = 1;j<=len;j++){
if(a[j].bo == false){
sum += a[j].x;
}
}
int t = sum%3;
if( t== 0){//找到
for(int k = 1;k<=len;k++){
if(a[k].bo == false){
cout<<a[k].x;
}
}
cout<<endl;
}
else{ // 此数不符合时
del(t,len);
}
}
}
int main()
{
freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
char s[N];
cin>>s;
int len = strlen(s);
for(int i = 1;i<=len;i++)
{
a[i].x = s[i - 1] - '0';
a[i].bo = false;
}
fsort(1,len);
for(int k = 1;k<=len;k++)
{
a[k].rest = a[k].x %3;
}
find(len);
return 0;
}。

相关文档
最新文档