贪心算法经典例题(贪心算法的例题)

本篇文章给大家谈谈贪心算法经典例题,以及贪心算法的例题对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

五大常用算法之一:贪心算法

所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,换句话说,当考虑做何种选择的时候,我们只考虑对当前问题最佳的选择而不考虑子问题的结果。这是贪心算法可行的第一个基本要素。贪心算法以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。 对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。

当一个问题的最优解包含其子问题的最优解时册祥,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心算法求解的关键特征。

值得注意的是,贪心算法并不是完全不可以使用,贪心策略一旦经过证明成立后,它就是一种高效的算法。比如, 求最小生成树的Prim算法和Kruskal算法都是漂亮的贪心算法 。

贪心算法还是很常见的算法之一,这是由于它简单易行,构造贪心策略不是很困难。

可惜的是,它需要证明后才能真正运用到题目的算法中。

一般来说,贪心算法的证明围绕着:整个问题的最优解一定由在贪心策略中存在的子问题的最优解得来的。

对于例题中的3种贪心策略,都是无法成立(无法被证明)的,解释如下:

贪心策略:选取价值最大者。反例:

W=30

物品:A B C

重量:28 12 12

价值:30 20 20

根据策略,首先选取物品A,接下来就无法再选取了,可是,选取B、C则更好。

(2)贪心策略:选取重量最小。它的反例与第一种策略的反例差不多。

(3)贪心策略:选取单位重量价值最大的物品。反例:

W=30

物品:A B C

重量:28 20 10

价值:28 20 10

根据策略,三种物品单位重量价值一样,程序无法依据现有策略作出判断,如果选择A,则答案错误。但是果在条件中加一句当遇见单位价值相同的时候,优先装重量小的,这样的问题就可以解决.

所以需要说明的是,贪心算法可以与随机化算法一起使用,具体的例子就不再多举了。(因为这一类算法普及性不高,而且技术含量是非常高的,需要通过一些反例确定随机的对象是什么,随机程度如何,但也是稿州不能保证完全正确,只能是极大州敬搏的几率正确)。

[img]

求一个算法(贪心算法)

首先,无所谓哪里密集哪里不密集的说法,这是人为的区分,需要首先遍历全部格子才能行卜禅确定,是最慢的算法,全部遍历过了就可以得出最优的路线了.

既然用贪心算法,为了思考方便,可以假设棋盘无穷大,算法的目的是判断下一步该往右走还是往下走,思想如下:

判断当前格子右、下两个相邻的格子是否有金块,档尘情形如下:

1)如果一个有一个没有,则往有金块的格子走

2)如果都没有或都有,则需要判断往哪个方向走能更快的拾到下一个金块,方法如下:

让机器人假设地各往两个方向走一步,然后对当前格子作判断情形如下:

A)一个格弊拦子继续走能拾到金块,另一个不能,则上一步往该格子走

B)如果仍旧都有或都没有,重复2)直到找到符合A)的情形。

假设棋盘是N*N个格子,则贪心算法最坏的情形是要遍历整个棋盘,比如只有第一个格子有金块时,就需要遍历整个棋盘才能确定走法。最好的情形也需要遍历4*N个格子。

时间复杂度上来算的话,应该是O(nLogn)

贪心算法的例题分析

例题1、

[0-1背包问题]有一个背包,背包容量是M=150。有7个物品,物品不可以分割成任意大小。

要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。

物品 A B C D E F G

重量 35kg 30kg 6kg 50kg 40kg 10kg 25kg

价值 10$ 40$ 30$ 50$ 35$ 40$ 30$

分析:

目标函数:∑pi最大

约束条件是装入的物品总重量不超过背包容量:∑wi=M(M=150)

⑴根据贪心的策略,每次挑选价值最大的物品装入背包,得到的结果是否最优?

⑵每次挑选所占重量最小的物品装入是否能得到最优解?

⑶每次选取单位重档李量价值最大的物品,成为解本题的策略。

值得注意的是,贪心算法并不是完全不可以使用,贪心策略一旦经过证明成立后,它就是一种高效的算法。

贪心算法还是很常见的算法之一,这是由于它简单易行,构造贪心策略不是很困难。

可惜的是,它需要证明后才能真正运用到题目的算法中。

一般来说,贪心算法的证明围绕着:整个问题的最优解一定由在贪心策略中存在的子问题的最优解得来的。

对于例题中的3种贪心策略,都是无法成立(无法被证明)的,解释如下:

⑴贪心策略:选取价值最大者。

反例:

W=30

物品:A B C

重量:28 12 12

价值:30 20 20

根据策略,首先选取物品A,接下来就无法再选取了,可是,选取B、C则更好。

⑵贪心策略:选取重量最小。它的反例与第一种策略的反例差不多。

⑶贪心策略:选取单位重量价值最大的物品。

反例:

W=30

物品:A B C

重量:28 20 10

价值:28 20 10

根据策略,三种物品单位重量价值一样,程序无法依据现有策略作出判断,如果选择A,则答案错误。

【注意:如果物品可以分割为任意大小,那么策略3可得最优解】

对于选取单位重量价值最大的物品这个策略,可以再加一条优化的规则:对于单位重量价值一样的,则优先选择重量小的!这样,上面的反带蚂例就解决了。

但是,如果题目是如下所示,这个策略就也不行了。

W=40

物品:A B C

重量:25 20 15

价值:25 20 15

附:本题是个DP问题,用贪心法并不一定可以求得最优解,以后了解了动态规划算法后本题就有了新的解法。

例题2、

马踏棋盘的贪心算法

123041-23 XX

【问题描述】

马的遍历问题。在8×8方格的棋盘上,从任意指定方格出发,为马寻找一条走遍棋盘每一格并且只经过一次的一条路径。

【初步设计】

首先这是一个搜索问题,运用深度优先搜索进行求解。算法如下:

⒈ 输入初始位置坐标x,y;

⒉ 步骤 c:

如果c 64输出一个解,返回上一步骤c--

(x,y) ← c

计算(x,y)的八个方位的子结点,选出那些可行的子结点

循环遍历所有可行子结点,步骤c++重复2

显然⑵是一个递归调用的过程,大致如下:

C++程序: #define N 8void dfs(int x,int y,int count){    int i,tx,ty;    if(countN*N)    {        output_solution();//输出一个解        return;    }    for(i=0; i8; i++)    {        tx=hn[i].x;//hn[]保存八个方位子结点        ty=hn[i].y;        s[tx][ty]=count;        dfs(tx,ty,count+1);//递归调用        s[tx][ty]=0;    }}Pascal程序: ProgramYS;ConstFXx:array[1..8]of-2..2=(1,2,2,1,-1,-2,-2,-1);FXy:array[1..8]of-2..2=(2,1,-1,-2,-2,-1,1,2);VarRoad:array[1..10,1..10]ofinteger;x,y,x1,y1,total:integer;ProcedureFind(x,y:integer);varNx,Ny,i:integer;BeginFori:=1to8dobegin{8个方向}If(x+FXx[i]in[1..8])and(y+FXy[i]in[1..8])Then{确定新坐标是否越界}IfRoad[x+Fxx[i],y+Fxy[i]]=0Thenbegin{判断是否走过}Nx:=x+FXx[i];Ny:=y+FXy[i];Road[Nx,Ny]:=1;{建立新坐标}If(Nx=x1)蠢蠢埋and(Ny=y1)Theninc(total)elseFind(Nx,Ny);{递归}Road[Nx,Ny]:=0{回朔}endendEnd;BEGIN{Main}Total:=0;FillChar(Road,sizeof(road),0);Readln(x,y);{读入开始坐标}Readln(x1,y1);{读入结束坐标}If(x10)or(y10)or(x110)or(y110)Thenwriteln('Error'){判断是否越界}ElseFind(x,y);Writeln('Total:',total){打出总数}END.这样做是完全可行的,它输入的是全部解,但是马遍历当8×8时解是非常之多的,用天文数字形容也不为过,这样一来求解的过程就非常慢,并且出一个解也非常慢。

怎么才能快速地得到部分解呢?

【贪心算法】

其实马踏棋盘的问题很早就有人提出,且早在1823年,J.C.Warnsdorff就提出了一个有名的算法。在每个结点对其子结点进行选取时,优先选择‘出口’最小的进行搜索,‘出口’的意思是在这些子结点中它们的可行子结点的个数,也就是‘孙子’结点越少的越优先跳,为什么要这样选取,这是一种局部调整最优的做法,如果优先选择出口多的子结点,那出口少的子结点就会越来越多,很可能出现‘死’结点(顾名思义就是没有出口又没有跳过的结点),这样对下面的搜索纯粹是徒劳,这样会浪费很多无用的时间,反过来如果每次都优先选择出口少的结点跳,那出口少的结点就会越来越少,这样跳成功的机会就更大一些。这种算法称为为贪心算法,也叫贪婪算法或启发式算法,它对整个求解过程的局部做最优调整,它只适用于求较优解或者部分解,而不能求最优解。这样的调整方法叫贪心策略,至于什么问题需要什么样的贪心策略是不确定的,具体问题具体分析。实验可以证明马遍历问题在运用到了上面的贪心策略之后求解速率有非常明显的提高,如果只要求出一个解甚至不用回溯就可以完成,因为在这个算法提出的时候世界上还没有计算机,这种方法完全可以用手工求出解来,其效率可想而知。

收集各类贪心算法(C语言编程)经典题目

举个例子,假如你买东西,老板需要找给你99分钱,他有棚好上面面值分别为25分,10分,5分,1分的硬币(都是假如,不符合实际),他租正得找你3个25分,2个10分的,弊和悔4个1分的才为最佳方案!

用贪心算法编写程序实现!

main()

{

int

i,a[5],b[4],c[4];

/*

define

the

type

of

the

money*/

a[1]=25;

a[2]=10;

a[3]=5;

a[4]=1;

printf("please

input

you

money

(fen):\n");

scanf("%d",b[0]);

for

(i=1;i=4;i++)

{

b[i]=b[i-1]%a[i];

/*take

n

25

off

and

money

left*/

c[i]=(b[i-1]-b[i])/a[i];

/*

n

*/

printf("%d

is

%d\n",a[i],c[i]);

}

getch();

}

关于贪心算法经典例题和贪心算法的例题的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

标签列表