贪心算法经典例题
经典贪心题
贪心算法是一种在解决问题的过程中追求局部最优的算法,对于一个有多种属性的事物来说,贪心算法会优先满足某种条件,追求局部最优的同时希望达到整体最优的效果。
以下是一些经典的贪心算法问题:1. 背包问题:给定一组物品,每个物品都有自己的重量和价值,背包的总容量有限。
贪心算法需要选择物品以最大化背包中物品的总价值,同时不超过背包的总容量。
这种问题可以有多种变体,例如分数背包问题和完全背包问题。
2. 硬币找零问题:给定一组硬币的面值和数量,以及需要找零的金额。
贪心算法需要选择硬币以最小化找零的总数量。
这个问题可以通过从大到小排序硬币,并从最大面值的硬币开始选择,直到找零的金额达到所需的总金额。
3. 区间选点问题:给定一系列闭区间,每个闭区间都有一个起始点和结束点。
贪心算法需要选择尽量少的点,使得每个闭区间内至少有一个点被选中。
这个问题可以通过对结束点进行排序,并从左到右选择结束点,直到下一个要选择的结束点与上一个选择的结束点之间的距离大于当前选择的结束点与上一个选择的结束点之间的距离为止。
4. 区间覆盖问题:给定一系列闭区间,贪心算法需要选择尽量少的区间,使得所有区间都被覆盖。
这个问题可以通过对每个闭区间的左端点进行排序,并从左到右选择左端点,直到下一个要选择的左端点与上一个选择的左端点之间的距离大于当前选择的左端点与上一个选择的左端点之间的距离为止。
5. 排班问题:给定一组员工和他们的班次需求,以及一组工作日的日程安排。
贪心算法需要为员工分配班次,以最小化总工作时间并满足所有工作日的需求。
这个问题可以通过从可用的班次中选择最长的班次,并从左到右分配员工,直到所有员工都被分配到一个班次为止。
这些问题是贪心算法的经典示例,它们展示了贪心算法在解决优化问题中的广泛应用。
贪心算法练习题
贪心算法1.喷水装置(一)描述现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以它为中心的半径为实数Ri(0<Ri<15)的圆被湿润,这有充足的喷水装置i(1<i<600)个,并且一定能把草坪全部湿润,你要做的是:选择尽量少的喷水装置,把整个草坪的全部湿润。
输入第一行m表示有m组测试数据每一组测试数据的第一行有一个整数数n,n表示共有n个喷水装置,随后的一行,有n个实数ri,ri表示该喷水装置能覆盖的圆的半径。
输出输出所用装置的个数样例输入252 3.2 4 4.5 6101 2 3 1 2 1.2 3 1.1 1 2样例输出25根据日常生活知道,选择半径越大的装置,所用的数目越少。
因此,可以先对半径排序,然后选择半径大的。
另外,当装置刚好喷到矩形的顶点时,数目最少。
此时只要装置的有效喷水距离的和不小于20时,输出此时的装置数目即可。
2.喷水装置(二)时间限制:3000 ms | 内存限制:65535 KB难度:4描述有一块草坪,横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=10000)个点状的喷水装置,每个喷水装置i喷水的效果是让以它为中心半径为Ri的圆都被润湿。
请在给出的喷水装置中选择尽量少的喷水装置,把整个草坪全部润湿。
输入对于每一组输入,输出最多能够安排的活动数量。
每组的输出占一行样例输入221 1010 1131 1010 1111 20样例输出12提示注意:如果上一个活动在T时间结束,下一个活动最早应该在T+1时间开始。
解题思路:这是一个贪心法中选择不相交区间的问题。
先对活动结束时间从小到大排序,排序的同时活动的起始时间也要跟着变化。
而且,结束时间最小的活动一定会安排,不然这段时间就白白浪费了。
后一个活动的起始时间如果比前一个活动的结束时间大,即两个活动没有相交时间,就把这个活动也安排上。
c++贪心算法经典例题
c++贪心算法经典例题
经典的贪心算法例题有很多,以下是其中几个常见的例题:
1. 分糖果问题:
有一群小朋友,每个人都有一个评分。
现在需要给他们分糖果,要求评分高的小朋友比他旁边评分低的小朋友拥有更多的糖果。
求至少需要准备多少糖果。
2. 区间覆盖问题:
给定一个区间集合,每个区间表示一个工作时间段。
现在需要选择尽可能少的区间,覆盖整个时间范围。
求最少需要选择多少个区间。
3. 最佳买卖股票时机:
给定一个股票的价格列表,可以任意次数买入和卖出股票。
但是同一时间只能持有一支股票,求能够获得的最大利润。
4. 最大会议安排:
给定一系列的会议,每个会议有开始时间和结束时间。
要求安排尽可能多的会议,使得它们不会发生时间上的冲突。
5. 跳跃游戏:
给定一个非负整数数组,每个元素表示在该位置上能够跳跃的最大长度。
初始位置在第一个元素,判断能否跳到最后一个元素。
以上仅是一些常见的例题,贪心算法广泛应用于各种问题中。
在解决实际问题时,需要根据具体情况设计贪心策略,找到合适的贪心策略才能得到正确的解答。
第六章-贪心算法
//每堆牌的张数减去平均数
i:=1;j:=n;
while (a[i]=0) and (i<n) do inc(i);
//过滤左边的0
while (a[j]=0) and (j>1) do dec(j);
//过滤右边的0
while (i<j) do
begin
inc(a[i+1],a[i]); a[i]:=0; inc(step); inc(i); while (a[i]=0) and (i<j) do inc(i);
现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。 例如 N=4,4 堆纸牌数分别为: ① 9 ② 8 ③ 17 ④ 6
移动3次可达到目的: 从 ③ 取4张牌放到④(9 8 13 10)->从③取3张牌放到 ②(9 11 10 10)> 从②取1张牌放到①(10 10 10 10)。 【输入格式】 N(N 堆纸牌,1 <= N <= 100) A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000) 【输出格式】 所有堆均达到相等时的最少移动次数。 【样例输入】Playcard.in
输出n;
//删去串首可能产生的无用零
【例6】拦截导弹问题(NOIP1999) 某国为了防御敌国的导弹袭击,开发出一种导弹拦截系统,但是这种拦
截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每 一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭,由 于该系统还在试用阶段。所以一套系统有可能不能拦截所有的导弹。
因此,贪心不能简单进行,而需要全面的考虑,最后得到证明。
【例3】排队打水问题
贪心算法几个经典例子c语言
贪心算法几个经典例子c语言1. 零钱兑换问题题目描述:给定一些面额不同的硬币和一个总金额,编写一个函数来计算可以凑成总金额所需的最少的硬币个数。
如果没有任何一种硬币组合能够凑出总金额,返回 -1。
贪心策略:每次选择面额最大的硬币,直到凑出总金额或者无法再选择硬币为止。
C语言代码:int coinChange(int* coins, int coinsSize, int amount){int count = 0;for(int i = coinsSize - 1; i >= 0; i--){while(amount >= coins[i]){amount -= coins[i];count++;}}return amount == 0 ? count : -1;}2. 活动选择问题题目描述:有 n 个活动,每个活动都有一个开始时间和结束时间,选择一些活动使得它们不冲突,且能够参加的活动数最多。
贪心策略:每次选择结束时间最早的活动,直到所有活动都被选择或者无法再选择为止。
C语言代码:typedef struct{int start;int end;}Activity;int cmp(const void* a, const void* b){return ((Activity*)a)->end - ((Activity*)b)->end;}int maxActivities(Activity* activities, int n){qsort(activities, n, sizeof(Activity), cmp);int count = 1;int end = activities[0].end;for(int i = 1; i < n; i++){if(activities[i].start >= end){count++;end = activities[i].end;}}return count;}3. 跳跃游戏题目描述:给定一个非负整数数组,你最初位于数组的第一个位置。
贪心算法经典例题
贪心算法经典例题引言贪心算法是一种常见的算法策略,它在求解问题时每一步都选择当前状态下的最优解,从而最终得到全局最优解。
本文将介绍一些经典的贪心算法例题,帮助读者更好地理解贪心算法的思想和应用。
背景知识在讨论贪心算法之前,我们先了解一些背景知识。
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] + "张");}}分析与总结通过贪心算法,我们可以得到找零纸币的最优解。
贪心算法题库
贪心算法是一种在每一步选择中都采取当前情况下的局部最优选择,并希望导致结果是全局最优解的算法。
下面是一些贪心算法的题目和解答:1. 旅行商问题(Travelling Salesman Problem):问题描述:给定一个城市列表和一个距离列表,要求找出一条路径,使得路径上的所有城市都经过,且总距离最短。
贪心算法解法:首先对城市按照距离进行排序,然后从最近的两个城市开始,每次都选择距离当前位置最近的两个城市,直到遍历完所有城市。
由于贪心算法每次选择的都是当前情况下的最优解,因此最终得到的路径总距离是最短的。
2. 背包问题(Knapsack Problem):问题描述:给定一组物品,每个物品都有自己的重量和价值,要求在不超过背包总重量的情况下,如何选择物品使得背包中物品的总价值最大。
贪心算法解法:按照物品的重量对物品进行排序,然后每次选择重量最小的物品,直到背包已满或无物品可选。
由于贪心算法每次选择的都是当前情况下的最优解,因此最终得到的方案总是可以找到一个大于等于当前最优解的方案。
3. 网格找零问题(Currency Change Problem):问题描述:给定一组面值不同的硬币,要求用最少的组合方式从一定金额中找零。
贪心算法解法:首先对硬币面值进行排序,然后每次使用当前面值最小的硬币进行组合,直到金额为零或无硬币可选。
贪心算法在此问题中的思路是每次选择最小的硬币进行使用,这样可以保证找零的最小数量。
以上题目和解答只是贪心算法的一部分应用,实际上贪心算法在许多其他领域也有广泛的应用,例如网页布局优化、任务调度、网络流等等。
贪心算法的优势在于其简单易懂、易于实现,但也有其局限性,例如无法处理一些存在冲突的情况或最优解不唯一的问题。
因此在实际应用中需要根据具体问题选择合适的算法。
贪心法例题
贪心法3.1 排队接水有n 个人在一个水龙头前排队接水,假如每个人接水的时间为T i ,请编程找出这n 个人排队的一种顺序,使得n 个人的平均等待时间最小。
【输入】输入文件共两行,第一行为n ;第二行分别表示第1个人到第n 个人每人的接水时间T 1,T 2,…,T n ,每个数据之间有1个空格。
【输出】输出文件有两行,第一行为一种排队顺序,即1到n 的一种排列;第二行为这种排列方案下的平均等待时间(输出结果精确到小数点后两位)。
【样例】 water.in water.out 10 3 2 7 8 1 4 9 6 10 5 56 12 1 99 1000 234 33 55 99 812 291.90 【算法分析】 平均等待时间是每个人的等待时间之和再除以n ,因为n 是一个常数,所以等待时间之和最小,也就是平均等待时间最小。
假设是按照1~n 的自然顺序排列的,则这个问题就是求以下公式的最小值:∑∑==⎪⎪⎭⎫⎝⎛=+⋯⋯+++⋯⋯++++++=ni i j j n T T T T T T T T T T total 1121321211)()()(如果用穷举的方法求解,就需要我们产生n 个人的所有不同排列,然后计算每种排列所需要等待的时间之和,再“打擂台”得到最小值,但这种方法需要进行n!次求和以及判断,时间复杂度很差! 其实,我们认真研究一下上面的公式,发现可以改写成如下形式:∑=--+=++⋯⋯+-+-+=ni i n n T i n T T T n T n nT total 11321)1(2)2()1(这个公式何时取最小值呢?对于任意一种排列k 1, k 2, k 3, …, k n ,当1k T ≤2k T ≤3k T ≤…≤n k T 时,total取到最小值。
如何证明呢?方法如下: 因为n j i k k k k k T T j n T i n T n nT total +⋯++-+⋯++-+⋯+-+=)1()1()1(21假设i <j ,而i k T <j k T ,这是的和为total 1,而把k i 和kj 互换位置,设新的和为total 2,则:))(())(1())(1())1()1(()1()1(12i j i j i j j i i j k k k k k k k k k k T T i j T T j n T T i n T j n T i n T j n T i n total total total --=-+---+-=+-++--+-++-=-=∆我们发现上述△total 恒大于0,所以也说明了任何次序的改变,都会导致等待时间的增加。
c++贪心算法经典例题
c++贪心算法经典例题和详解贪心算法(Greedy Algorithm)是一种优化问题解决方法,其基本思想是每一步都选择当前状态下的最优解,以期望达到全局最优解。
贪心算法的特点是每一步都要做出一个局部最优的选择,而这些局部最优选择最终构成了全局最优解。
下面是一个经典的贪心算法例题以及详解:例题:活动选择问题(Activity Selection Problem)假设有一个需要在同一时段使用同一个资源的活动集合,每个活动都有一个开始时间和结束时间。
设计一个算法,使得能够安排最多数量的互不相交的活动。
# 输入:-活动的开始时间数组`start[]`。
-活动的结束时间数组`end[]`。
# 输出:-选择的互不相交的活动的最大数量。
# 算法详解:1. 首先,将活动按照结束时间从小到大排序。
2. 选择第一个活动,并将其加入最终选择的集合中。
3. 对于剩下的活动,选择下一个结束时间最早且与前一个活动不冲突的活动。
4. 重复步骤3,直到所有活动都被选择。
```cpp#include <iostream>#include <algorithm>#include <vector>using namespace std;// 定义活动结构体struct Activity {int start, end;};// 比较函数,用于排序bool compareActivities(Activity a, Activity b) {return a.end < b.end;}// 贪心算法解决活动选择问题void activitySelection(vector<Activity>& activities) {// 按照结束时间排序sort(activities.begin(), activities.end(), compareActivities);// 第一个活动总是被选中cout << "Selected activity: (" << activities[0].start << ", " << activities[0].end << ")" << endl;// 选择其余活动int lastSelected = 0;for (int i = 1; i < activities.size(); i++) {// 如果当前活动的开始时间大于等于上一个选择的活动的结束时间,则选择该活动if (activities[i].start >= activities[lastSelected].end) {cout << "Selected activity: (" << activities[i].start << ", " << activities[i].end << ")" << endl;lastSelected = i;}}}int main() {vector<Activity> activities = {{1, 2}, {3, 4}, {0, 6}, {5, 7}, {8, 9}, {5, 9}};cout << "Activities before sorting:" << endl;for (const Activity& activity : activities) {cout << "(" << activity.start << ", " << activity.end << ") ";}cout << endl;activitySelection(activities);return 0;}```在这个例子中,我们首先定义了一个活动的结构体`Activity`,然后编写了一个比较函数`compareActivities` 用于排序。
c++贪心算法经典例题
c++贪心算法经典例题摘要:一、贪心算法简介1.贪心算法的定义2.贪心算法的特点3.贪心算法适用的问题类型二、C++贪心算法经典例题1.背包问题a.0-1 背包问题b.完全背包问题c.动态背包问题2.最小生成树a.Kruskal 算法b.Prim 算法3.单源点最短路径a.Dijkstra 算法b.Floyd-Warshall 算法4.最长公共子序列a.贪心算法实现b.动态规划实现正文:一、贪心算法简介贪心算法(Greedy Algorithm)是一种求解最优解的方法。
它是在对问题求解时,总是做出在当前看来是最好的选择。
贪心算法并不追求整体最优解,只希望得到较为满意的解。
贪心算法的关键是贪心策略的选择,必须满足无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关。
贪心算法适用的问题类型包括背包问题、最小生成树、单源点最短路径和最长公共子序列等。
二、C++贪心算法经典例题1.背包问题背包问题(Knapsack Problem)是一种典型的贪心算法问题。
它描述的是有一个背包,有一定的容量,需要装载若干物品,每个物品有一定的价值和重量,要求在不超过背包容量的前提下,如何选择装载物品使得背包中的物品总价值最大。
背包问题可以分为0-1 背包问题、完全背包问题和动态背包问题。
2.最小生成树最小生成树(Minimum Spanning Tree,简称MST)是一种图论中的算法问题。
给定一个加权连通图,求解一个生成树,使得该生成树中所有边的权值之和最小。
最小生成树的经典算法有Kruskal 算法和Prim 算法。
3.单源点最短路径单源点最短路径(Single Source Shortest Path)问题是在一个图中,从源点出发到其他所有顶点的最短路径。
经典算法包括Dijkstra 算法和Floyd-Warshall 算法。
4.最长公共子序列最长公共子序列(Longest Common Subsequence,简称LCS)问题是求两个序列中最长的公共子序列。
贪心算法经典例题
贪心算法经典例题贪心算法是一种求解最优问题的算法思想,其核心理念是每一步都选择当前最优的策略,从而达到全局最优解。
贪心算法可以应用于许多经典问题,下面将介绍几个常见的贪心算法经典例题及相关参考内容。
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. 零钱兑换问题:给定一些面值不同的硬币和一个金额,要求用最少的硬币凑出这个金额。
2. 最小生成树问题:给定一个无向带权图,要求用最小的权值构建一棵生成树。
3. 背包问题:给定一些物品和一个背包,每个物品有对应的价值和重量,要求在背包容量限制下,选取物品使得总价值最大。
4. 活动安排问题:有若干个活动需要分配一段时间,每个活动有对应的开始时间和结束时间,要求选取尽可能多的活动,使得任两个安排的活动时间不重叠。
5. 单源最短路径问题:给定一个有向带权图和一个起始节点,要求求出从起始节点到其他所有节点的最短路径。
6. 任务调度问题:有若干个需要完成的任务和多个可执行任务的处理器,要求将任务分配给处理器,使得执行总时间最小。
7. 区间覆盖问题:给定一些区间,要求用尽可能少的区间覆盖整个线段。
8. 哈夫曼编码问题:给定一些字符及其对应的出现概率,要求用最短的编码方式表示这些字符。
贪心法例题
贪心法例题
贪心法是一种常见的算法思想,在解决一些优化问题时被广泛应用。
下面是几个贪心法的例题:
1. 分发糖果
给定一个数组 ratings,表示一群孩子的评分,现在需要给这些孩子分发糖果。
规定每个孩子至少分配到一个糖果,且评分更高的孩子必须得到更多的糖果。
问最少需要准备多少个糖果。
2. 会议室安排
给定一组会议,每个会议有开始时间和结束时间,现在需要在有限的会议室内安排这些会议,使得尽可能多的会议得以举行。
请问最多可以安排多少个会议。
3. 分割回文串
给定一个字符串 s,将其分割成一些子串,使得每个子串都是回文串。
请问最少需要分割多少次。
4. 零钱兑换
给定一组硬币的面值和一个总金额 amount,现在需要用这些硬币来找零。
请问最少需要多少个硬币才能凑出总金额。
以上例题均可以使用贪心法来解决,具体实现方式需要根据题目要求进行调整。
贪心法在实际应用中的效果取决于问题本身的特点,不适用于所有问题。
- 1 -。
贪心算法的例子
贪心算法的例子
贪心算法是一种解决优化问题的算法,它通常用于在一组选择中作出最优决策。
在贪心算法中,每次选择都是当前状态下的最优解,而不考虑将来可能出现的情况。
下面是一些贪心算法的例子。
1. 零钱兑换问题
假设你有一些硬币,每个硬币的面值分别为1、5、10、50、100。
现在要找零n元,最少需要多少个硬币呢?在贪心算法中,我们每次选择最大面值的硬币,直到凑够n元为止。
2. 区间覆盖问题
假设你有一些区间,每个区间用起点和终点表示。
现在要用尽可能少的区间覆盖所有的点,怎么办?在贪心算法中,我们每次选择覆盖范围最大的区间,直到所有点都被覆盖为止。
3. 最小生成树问题
假设你有一个连通无向图,每条边都有一个权值。
现在要选择一些边,构成一棵树,使得总权值最小,怎么办?在贪心算法中,我们每次选择与当前树相连的边中,权值最小的边,直到所有点都被覆盖为止。
4. 背包问题
假设你有一个背包,容量为C,有一些物品,每个物品有重量w 和价值v。
现在要选择一些物品,放入背包中,使得总重量不超过C,总价值最大,怎么办?在贪心算法中,我们每次选择单位价值最大的物品,直到背包装满为止。
这些都是贪心算法的例子,贪心算法虽然看起来简单,但是它在某些情况下可以得到最优解,而且时间复杂度也比较低。
贪心算法练习题
贪心算法练习题贪心算法是一种常用的解决问题的思想和方法,它通常用于求解优化问题。
贪心算法的核心思想是:在每一步选择中都采取当前状态下最优的选择,从而希望最终能够达到全局最优。
在实际应用中,贪心算法常用于解决一些分类问题,如最小生成树、最短路径、背包问题等。
下面,将给出一些贪心算法的练习题,帮助读者更好地理解和掌握贪心算法的应用。
1. 零钱兑换问题假设我们有不同面额的硬币,如 1 美元、2 美元、5 美元等,我们希望找零 n 美元的时候,最少需要多少个硬币。
请用贪心算法解决此问题,并给出相应的代码实现。
2. 区间覆盖问题给定一个区间集合,选择尽可能少的区间,使得这些区间的并集能够覆盖全部的区间。
请使用贪心算法解决此问题,并给出相应的代码实现。
3. 活动选择问题给定 n 个活动的开始时间和结束时间,选择尽可能多的不相交的活动。
请使用贪心算法解决此问题,并给出相应的代码实现。
4. 任务调度问题假设我们有 n 个任务和 m 台执行任务的机器,每个任务需要一个单位的时间,在每台机器上只能执行一个任务。
如何安排任务,使得所有任务都能够被执行,并且时间最短。
请使用贪心算法解决此问题,并给出相应的代码实现。
以上是一些常见的贪心算法练习题,通过解决这些问题,读者可以更加深入地理解和掌握贪心算法的应用。
当然,在实际应用中,贪心算法并不是万能的,它只能求解一些特定类型的优化问题,对于其他类型问题的求解可能并不适用。
因此,在使用贪心算法时,需要仔细分析问题的特性,判断是否适用贪心算法,并注意贪心选择的合理性。
通过不断练习和实践,读者可以逐渐掌握贪心算法的应用技巧,提高问题求解的效率和准确性。
最后,希望读者能够善于思考,灵活运用贪心算法解决实际问题,并在实践中不断学习和进步。
贪心算法作为一种常用的解决问题的思想和方法,对于提高算法设计和分析能力具有重要意义。
贪心算法
贪心算法专题实例解析【例1】删数问题Description键盘输人一个高精度的正整数N(<=240位),去掉其中任意s个数字后剩下的数字按原左右次序将组成一个新的正整数.编程对给定的N和s,寻找一种方案使得剩下的数字组成的新数最小。
InputnsOutput最后剩下的最小数【例2】取数游戏Description给出2n(n<=100)个自然数(数小于等于30000)。
游戏双方分别为A方(计算机方)和B方(对弈的人)。
只允许从数列两头取数。
A先取,然后双方依次轮流取数。
取完时,谁取的数字总和最大为取胜方;若双方和相等,属于A胜。
试问A方是否有必胜的策略。
Input键盘输入N和2*N个自然数Output共3N+2行,其中前3*N行为游戏经过。
每3行分别为A方所取的数和B方所取的数及B方取数前应给予的适当提示,让游戏者选择哪一头的数(L/R----左端或右端)。
最后2行分别为A方取得的数和裕B方取得的数和。
【例3】0/1背包问题Description给定一个载重量为weight的背包,n个物品,其重量分别为w[i],价值分别为p[i],1<=i<=n,物体或者被装入背包,或者不被装入背包,只有两种选择。
要求把物品装入背包,并使包内物品价值最大。
Sample Input11 {weight}4 {n}2 4 6 7 {w[i]}6 10 12 13 {p[i]}Sample Output0 1 0 123【例4】活动选择Description假设有一个需要使用某一资源的n个活动组成的集合是,s{1,2,…,n}。
该资源一次只能被一个活动所占用,每个活动有一个开始时间b[i]和结束时间e[i] (b[i]<e[i])。
若b[i]>=e[j]或b[j]>=e[i],则活动i和活动j兼容。
我们的任务是:选择由互相兼容的活动组成的最大集合。
Input (in.tzt)NB[1] e[1]…………B[n] e[n]Output (out.txt)共两行,第一行为满足要求的活动占用的时间t,第2行为最大集合中的活动序号,每个数据之间用一个空格隔开。
java贪心算法几个经典例子
java贪心算法几个经典例子
1. 零钱兑换问题
给定面额为1、5、10、25的硬币,以及一个需要兑换的金额,问最少需要多少硬币才能兑换成功。
解法:每次选择面额最大的硬币兑换,直到兑换完毕为止。
2. 分糖果问题
有m个糖果,要分给n个孩子,每个孩子至少分到一个糖果,且每个孩子分到的糖果数应尽量相近,求最小的糖果差。
解法:将m个糖果按照大小排序,依次将糖果分给n个孩子,每次将糖果分给最少的孩子。
3. 区间覆盖问题
给定多个区间,问最少需要选多少个区间才能覆盖全集。
解法:每次选择与当前未被覆盖的部分交集最大的区间添加到答案中,直到所有部分被覆盖完毕为止。
4. 任务调度问题
有n个任务需要完成,每个任务需要占用不同的时间,同时每个任务都有一个
最后期限,问如何调度任务才能最大程度地避免超时。
解法:将所有任务按照最后期限排序,依次将任务安排到最后期限之前的最近空闲时间点,尽量将任务时间安排得紧凑。
贪心算法例题
贪心算法例题
贪心算法是一种在每一步选择中都采取当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。
以下是一个贪心算法的例子:
问题描述:有100个人在一酒吧,一次酒局中大家都决定向其他每个人敬酒,但只有距离较近的人之间才能互敬。
酒局结束后,每人都记录下他们之间互敬了多少次。
现给出所有人的互敬次数,找出互敬次数最多的那个人。
贪心策略:从最多互敬次数的人开始,每次都选择能互敬次数最多的人,直到达到最大互敬次数为止。
具体实现:
1. 首先将所有人的互敬次数存入一个数组中。
2. 从数组中找到互敬次数最多的人,假设其互敬次数为max_times。
3. 从数组中删除所有互敬次数小于max_times的人,因为他们的互敬次数已经确定不会超过max_times。
4. 重复步骤2和3,直到数组为空。
这个贪心算法的例子中,每次选择都是基于当前情况下的最优选择,希望通过这种方式达到全局最优的结果。
贪心算法例题
贪心算法例题1木板制造问题描述现在需要制造N块木板,每块木板都有一个长度L和宽度W。
用来制造木板的机器在使用之前需要花1分钟时间进行调节,而且,如果在制造完一块木板L0×W0之后继续制造木板L1×W1,那么除非满足L0≤L1且W0≤W1,否则在制造L1×W1之前仍要花费1分钟进行调节。
现在给出欲制造的N块木板的尺寸,你的任务是确定至少需要花多长时间调节机器。
时间复杂度要求实现O(N2)时间复杂度的算法。
本题算法的最优时间复杂度为Θ(NlogN)。
2 雷达安装问题描述在笛卡尔坐标系上,我们认为海岸线是x轴,陆地在x轴下方,海洋在x轴上方,而每个岛屿都认为是海中的一个点。
现在要在海岸线上安装一些雷达,雷达的覆盖半径为d。
如果某个岛屿与离它最近的雷达之间的距离不超过d,这个岛屿就被监视了。
现在有N个岛屿需要监视,给出这N个岛屿的坐标,你的任务是确定为了监视所有的岛屿至少需要安装多少个雷达。
时间复杂度要求实现Θ(NlogN)时间复杂度的算法,而这也是本题时间复杂度的下限。
3 修理牛棚问题描述农夫约翰的牛棚是N个房间一个紧挨着一个排成一行的结构,每个房间的宽度都是1。
在一个暴风雨的夜晚,牛棚所有的天花板都被吹走了。
好在许多牛正在度假,所以牛棚没有住满,有些房间里面有牛,有些没有。
一共有S (1≤S≤N)个房间是有牛居住的。
农夫约翰打算至少先把有牛居住的房间的屋顶修好。
他的木材提供商只愿意提供M块木板,但是每块木板都可以是任意长度的。
农夫约翰想知道他至少需要购买多长的木板才能把牛都盖住。
时间复杂度要求实现O(NlogN)复杂度的算法。
本题算法的最优时间复杂度为Θ(N)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
贪心算法经典例题
发布日期:2009-1-8
浏览次数:1180
本资料需要注册并登录后才能下载!
·用户名密码验证码找回密码·您还未注册?请注册
您的账户余额为元,余额已不足,请充值。
您的账户余额为元。
此购买将从您的账户中扣除费用0.0元。
内容介绍>>
贪心算法经典例题
在求最优解问题的过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解,这种求解方法就是贪心算法。
从贪心算法的定义可以看出,贪心法并不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。
我们看看下面的例子
例1 均分纸牌(NOIP2002tg)
[问题描述] 有 N 堆纸牌,编号分别为 1,2,…, N。
每堆上有若干张,但纸牌总数必为 N 的倍数。
可以在任一堆上取若干张纸牌,然后移动。
移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。
现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。
例如 N=4,4 堆纸牌数分别为:
①9 ②8 ③17 ④ 6
移动3次可达到目的:
从③取 4 张牌放到④(9 8 13 10) -> 从③取 3 张牌放到②(9 11 10 10)-> 从②取 1 张牌放到①(10 10 10 10)。
[输入]:键盘输入文件名。
文件格式:N(N 堆纸牌,1 <= N <= 100)
A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000)
[输出]:输出至屏幕。
格式为:所有堆均达到相等时的最少移动次数。
[输入输出样例]
a.in:
4
9 8 17 6
屏慕显示:3
算法分析:设a[i]为第i堆纸牌的张数(0<=i<=n),v为均分后每堆纸牌的张数,s为最小移到次数。
我们用贪心法,按照从左到右的顺序移动纸牌。
如第i堆(0<i<n)的纸牌数a[i]不等于平均值,则移动一次(即s加1),分两种情况移动:
(1)若a[i]>v,则将a[i]-v张纸牌从第I堆移动到第I+1堆;
(2)若a[i]<v,则将v -a[i]张纸牌从第I+1堆移动到第I堆;
为了设计的方便,我们把这两种情况统一看作是将a[I]-v张牌从第I堆移动到第I+1堆;移动后有:a[I]:=v;a[I+1]:=a[I+1]+a[I]-v;
在从第i+1堆中取出纸牌补充第i堆的过程中,可能会出现第i+1堆的纸牌数小于零
(a[i+1]+a[i]-v<0 )的情况。
如n=3,三堆纸牌数为(1,2,27)这时v=10,为了使第一堆数为10,要从第二堆移9张纸牌到第一堆,而第二堆只有2张纸牌可移,这是不是意味着刚才使用的贪心法是错误的呢?
我们继续按规则分析移牌过程,从第二堆移出9张到第一堆后,第一堆有10张纸牌,第二堆剩下-7张纸牌,再从第三堆移动17张到第二堆,刚好三堆纸牌数都是10,最后结果是对的,从第二堆移出的牌都可以从第三堆得到。
我们在移动过程中,只是改变了移动的顺序,而移动的次数不变,因此此题使用贪心法是可行的。
源程序:
var
i,n,s:integer;v:longint;
a:array[1..100]of longint;
f:text;fil:string;
begin
readln(fil);
assign(f,fil);reset(f);
readln(f,n);v:=0;
for i:=1 to n do begin
read(f,a[i]); inc(v,a[i]);
end;
v:=v div n; {每堆牌的平均数}
for i:=1 to n-1 do
if a[i]<>v then {贪心选择}
begin
inc(s);{移牌步数计数}
a[i+1]:=a[i+1]+a[i]-v;{使第i堆牌数为v}
end;{then}
writeln(s);
end.
利用贪心算法解题,需要解决两个问题:
一是问题是否适合用贪心法求解。
我们看一个找币的例子,如果一个货币系统有3种币值,面值分别为一角、五分和一分,求最小找币数时,可以用贪心法求解;如果将这三种币值改为一角一分、五分和一分,就不能使用贪心法求解。
用贪心法解题很方便,但它的适用范围很小,判断一个问题是否适合用贪心法求解,目前还没有一个通用的方法,在信息学竞赛中,需要凭个人的经验来判断何时该使用贪心算法。
二是确定了可以用贪心算法之后,如何选择一个贪心标准,才能保证得到问题的最优解。
在选择贪心标准时,我们要对所选的贪心标准进行验证才能使用,不要被表面上看似正确的贪心标准所迷惑,如下面的列子。
例2 (NOIP1998tg)设有n个正整数,将他们连接成一排,组成一个最大的多位整数。
例如:n=3时,3个整数13,312,343,连成的最大整数为:34331213
又如:n=4时,4个整数7,13,4,246连接成的最大整数为7424613
输入:N
N个数
输出:连接成的多位数
算法分析:此题很容易想到使用贪心法,在考试时有很多同学把整数按从大到小的顺序连接起来,测试题目的例子也都符合,但最后测试的结果却不全对。
按这种贪心标准,我们很容易找到反例:12,121 应该组成12121而非12112,那么是不是相互包含的时候就从小到大呢?也不一定,如:12,123 就是12312而非12112,这样情况就有很多种了。
是不是此题不能用贪心法呢?
其实此题是可以用贪心法来求解,只是刚才的贪心标准不对,正确的贪心标准是:先把整数化成字符串,然后再比较a+b和b+a,如果a+b>b+a,就把a排在b的前面,反之则把a排在b的后面。
源程序:
var
s:array[1..20] of string;
t:string;i,j,k,n:longint;
begin
readln(n);
for i:=1 to n do begin
read(k);
str(k,s[i]);
end;
for i:=1 to n-1 do
for j:=i+1 to n do
if s[i]+s[j]<s[j]+s[i] then
begin{交换}
t:=s[i];
s[i]:=s[j];
s[j]:=t;
end;
for i:=1 to n do write(s[i]);
end.
贪心算法所作的选择可以依赖于以往所作过的选择,但决不依赖于将来的选择,也不依赖于子问题的解,因此贪心算法与其它算法相比具有一定的速度优势。
如果一个问题可以同时用几种方法解决,贪心算法应该是最好的选择之一。