选自名师谈贪心特点与应用.docx
- 文档编号:3761154
- 上传时间:2022-11-25
- 格式:DOCX
- 页数:11
- 大小:57.57KB
选自名师谈贪心特点与应用.docx
《选自名师谈贪心特点与应用.docx》由会员分享,可在线阅读,更多相关《选自名师谈贪心特点与应用.docx(11页珍藏版)》请在冰豆网上搜索。
选自名师谈贪心特点与应用
一、引论
信息,人类社会发展的重要标志。
人类对信息的记载,可以追溯到原始社会。
在漫长的人类社会发展过程中,伴随着科学技术的发展,人类对客观世界的认识不断加深,现实世界的信息量急剧增大。
为了满足人们对大数据量信息处理的渴望,1946年世界上第一台电子数字计算机ENIAC应运而生。
在此后的半个世纪中,为解决各种实际问题,计算机算法学得到了飞速的发展。
线形规划、动态规划等一系列运筹学模型纷纷运用到计算机算法学中,解决了诸如经济决策等一系列现实问题。
在众多的计算机解题策略中,贪心策略可以算得上是最接近人们日常思维的一种解题策略,正基于此,贪心策略在各级各类信息学竞赛、尤其在对NPC类问题的求解中发挥着越来越重要的作用。
二、贪心策略的定义
【定义1】贪心策略是指从问题的初始状态出发,通过若干次的贪心选择而得出最优值(或较优解)的一种解题方法。
其实,从"贪心策略"一词我们便可以看出,贪心策略总是做出在当前看来是最优的选择,也就是说贪心策略并不是从整体上加以考虑,它所做出的选择只是在某种意义上的局部最优解,而许多问题自身的特性决定了该题运用贪心策略可以得到最优解或较优解。
三、贪心算法的特点
通过上文的介绍,可能有人会问:
贪心算法有什么样的特点呢?
我认为,适用于贪心算法解决的问题应具有以下2个特点:
1、贪心选择性质:
所谓贪心选择性质是指应用同一规则f,将原问题变为一个相似的、但规模更小的子问题、而后的每一步都是当前看似最佳的选择。
这种选择依赖于已做出的选择,但不依赖于未做出的选择。
从全局来看,运用贪心策略解决的问题在程序的运行过程中无回溯过程。
关于贪心选择性质,读者可在后文给出的贪心策略状态空间图中得到深刻地体会。
2、局部最优解:
我们通过特点2向大家介绍了贪心策略的数学描述。
由于运用贪心策略解题在每一次都取得了最优解,但能够保证局部最优解得不一定是贪心算法。
如大家所熟悉得动态规划算法就可以满足局部最优解,在广度优先搜索(BFS)中的解题过程亦可以满足局部最优解。
在遇到具体问题时,许多选手往往分不清哪些题该用贪心策略求解,哪些题该用动态规划法求解。
在此,我们对两种解题策略进行比较。
图一
[例1]删数问题
试题描述键盘输入一个高精度的正整数N,去掉其中任意S个数字后剩下的数字按左右次序组成一个新的正整数。
对给定的N和S,寻找一种删数规则使得剩下得数字组成的新数最小。
试题背景此题出自NOI94
试题分析这是一道运用贪心策略求解的典型问题。
此题所需处理的数据从表面上看是一个整数。
其实,大家通过对此题得深入分析便知:
本题所给出的高精度正整数在具体做题时将它看作由若干个数字所组成的一串数,这是求解本题的一个重要突破。
这样便建立起了贪心策略的数学描述。
[例2]数列极差问题
试题描述在黑板上写了N个正整数作成的一个数列,进行如下操作:
每一次擦去其中的两个数a和b,然后在数列中加入一个数a×b+1,如此下去直至黑板上剩下一个数,在所有按这种操作方式最后得到的数中,最大的max,最小的为min,则该数列的极差定义为M=max-min。
编程任务:
对于给定的数列,编程计算出极差M。
试题背景这是1997年福建队选拔赛的一道题目。
试题分析当看到此题时,我们会发现求max与求min是两个相似的过程。
若我们把求解max与min的过程分开,着重探讨求max的问题。
下面我们以求max为例来讨论此题用贪心策略求解的合理性。
讨论:
假设经(N-3)次变换后得到3个数:
a,b,max'(max'≥a≥b),其中max'是(N-2)个数经(N-3)次f变换后所得的最大值,此时有两种求值方式,设其所求值分别为
,
,则有:
=(a×b+1)×max'+1,
=(a×max'+1)×b+1 所以
-
=max'-b≥0若经(N-2)次变换后所得的3个数为:
m,a,b(m≥a≥b)且m不为(N-2)次变换后的最大值,即m<max'则此时所求得的最大值为:
=(a×b+1)×m+1 此时
-
=(1+ab)(max'-m)>0 所以此时不为最优解。
所以若使第k(1≤k≤N-1)次变换后所得值最大,必使(k-1)次变换后所得值最大(符合贪心策略的特点2),在进行第k次变换时,只需取在进行(k-1)次变换后所得数列中的两最小数p,q施加f操作:
p←p×q+1,q←∞即可(符合贪心策略特点1),因此此题可用贪心策略求解。
讨论完毕。
在求min时,我们只需在每次变换的数列中找到两个最大数p,q施加作用f:
p←p×q+1,q←-∞即可.原理同上。
这是一道两次运用贪心策略解决的一道问题,它要求选手有较高的数学推理能力。
[例3]最优乘车问题
试题描述 H城是一个旅游胜地,每年都有成千上万的人前来观光.为方便游客,巴士公司在各个旅游景点及宾馆、饭店等地都设置了巴士站,并开通了一些单向巴士线路。
每条单向巴士线路从某个巴士站出发,依次途径若干个巴士站,最终到达终点巴士站。
阿昌最近到H城旅游,住在CUP饭店。
他很想去S公园游玩。
听人说,从CUP饭店到S公园可能有也可能没有直通巴士。
如果没有,就要换乘不同线路的单向巴士,还有可能无法乘巴士到达。
现在用整数1,2,...,n给H城的所有巴士站编号,约定CUP饭店的巴士站编号为1,S公园巴士站的编号为N。
写一个程序,帮助阿昌寻找一个最优乘车方案,使他在从CUP饭店到S公园的过程中换车的次数最少。
试题背景出自NOI97
试题分析此题看上去很像一道搜索问题。
在搜索问题中,我们所求的使经过车站数最少的方案,而本题所求解的使换车次数最少的方案。
这两种情况的解是否完全相同呢?
我们来看一个实例:
图5
如图5所示:
共有5个车站(分别为a、b、c、d、e), 共有3条巴士线(线路A:
a→d;线路B:
a→b→c→e;线路C:
d→e)。
此时要使换车次数最少,应乘坐线路B的巴士,路线为:
a→b→c→e,换车次数为0;要使途经车站数最少,乘坐线路应为a→d→e,换车次数为1。
所以说使换车次数最少的路线和使途经车站数最少的方案不一定相同。
这使不能用搜索发求解此问题的原因之一。
原因之二,来自对数学模型的分析。
我们根据题中所给数据来建立一个图后会发现该图中存在大量的环,因而不适合用搜索法求解。
题目分析到这里,我们可以发现此题与NOI93的求最长路径问题有相似之处。
其实,此题完全可以套用上文所提到的Dijkstra算法来求解。
以上三道题只是使用了单一的贪心策略来求解的。
而从近几年的信息学奥林匹克竞赛的命题方向上看,题目更加灵活,同时测试数据较大,规定的出解时间较短。
在一些问题中,我们采用贪心策略对问题化简,从而使程序具有更高的效率。
[例4]最佳浏览路线问题
试题描述 某旅游区的街道成网格状(见图),其中东西向的街道都是旅游街,南北向的街道都是林荫道。
由于游客众多,旅游街被规定为单行道。
游客在旅游街上只能从西向东走,在林荫道上既可以由南向北走,也可以从北向南走。
阿隆想到这个旅游区游玩。
他的好友阿福给了他一些建议,用分值表示所有旅游街相邻两个路口之间的道路值得浏览得程度,分值从-100到100的整数,所有林荫道不打分。
所有分值不可能全是负值。
例如下图是被打过分的某旅游区的街道图:
阿隆可以从任一路口开始浏览,在任一路口结束浏览。
请你写一个程序,帮助阿隆寻找一条最佳的浏览路线,使得这条路线的所有分值总和最大。
试题背景 这道题同样出自NOI97,'97国际大学生程序设计竞赛的第二题(吉尔的又一个骑车问题)与本题是属于本质相同的题目。
试题分析由于林荫道不打分,也就是说,无论游客在林荫道中怎么走,都不会影响得分。
因题可知,若游客需经过某一列的旅游街,则他一定要经过这一列的M条旅游街中分值最大的一条,才会使他所经路线的总分值最大。
这是一种贪心策略。
贪心策略的目的是降维,使题目所给出的一个矩阵便为一个数列。
下一步便是如何对这个数列进行处理。
在这一步,很多人用动态规划法求解,这种算法的时间复杂度为O(n2),当林荫道较多时,效率明显下降。
其实在这一步我们同样可以采用贪心法求解。
这时的时间复杂度为O(n)。
七、总结
通过对贪心策略的分析,大家可以看出:
贪心策略作为一种高效算法,广泛地应用与信息学奥林匹克竞赛中。
即使表面上看起来与贪心策略关系甚微的题目,运用贪心算法也可使程序的运行效率大大提高。
因此,深刻理解贪心策略的数学模型、特点、理论基础、尤其是运用其基本思想解决具体问题是十分重要的。
希望本文能给参赛选手以一定的启发。
【部分试题及源程序】
1、吉尔的又一个乘车问题:
Inputfile:
jill.in
Jilllikestorideherbicycle,butsincetheprettycityofGreenhillswheresheliveshasgrown,Jilloftenusestheexcellentpublicbussystemforpartofherjourney.Shehasafoldingbicyclewhichshecarrieswithherwhensheusesthebusforthefirstpartofhertrip.Shefollowsthebusrouteuntilshereachesherdestinationofshecomestoapartofthecityshedoesnotlike.Inthelattereventshewillboardthebustofinishhertrip.
Throughyearsofexperience,Jillhasratedeachroadonanintegerscaleof"niceness".PositivenicenessvaluesindicateroadsJilllikes;negativevaluesareusedforroadsshedoesnotlike.Jillplanswheretoleavethebusandstartbicycling,aswellaswheretostopbicyclingandre-jointhebus,sothatthesumofnicenessvaluesoftheroadsshebicyclesonismaximized.Thismeansthatshewillsometimescyclealongaroadshedoesnotlike,providedthatitjoinsuptwootherpartsofherjourneyinvolvingroadsshelikesenoughtocompensate.ItmaybethatnopartoftherouteifsuitableforcyclingsothatJilltakesthebusforitsentireroute.Conversely,itmaybethatthewholerouteissoniceJillwillnotusethebusatall.
Sincetherearemanydifferentbusroutes,eachwithseveralstopsatwhichJillcouldleaveorenterthebus,shefeelsthatacomputerprogramcouldhelpheridentifythebestparttocycleforeachbusroute.
INPUT
Theinputfilecontainsinformationonseveralbusroutes.Thefirstlineofthefileisasingleintegerbrepresentingthenumberofroutedescriptionsinthefile.Theidentifierforeachroute(r)isthesequencenumberwithinthedatafiles,1≤r≤b.Eachroutedescriptionbeginswiththenumberofstopsontheroute:
anintegers,2≤s≤20,000onalinebyitself.Thenumberofstopsisfollowedbys-1lines,eachlinei(1≤i≤s)isanintegernirepresentingJill'sassessmentofthenicenessoftheroadbetweenthetwostopsiandi+1.
OUTPUT
Foreachrouterintheinputfile,yourprogramshouldidentifythebeginningbusstopiandtheendingbusstopjthatidentifythesegmentoftheroutewhichyieldsthemaximalsumofnicenessm=ni+ni+1+…+nj-1.Ifmorethanonesegmentismaximallynice,choosetheonewithlongestcycleride(largestj-i).Tobreaktiesinlongestmaximalsegments,choosethesegmentthatbeginswiththeearlieststop(lowesti).Foreachrouterintheinputfile,printalineintheform:
ThenicestpartofrouterisbetweenstopsiANDj.
However,ifthemaximalsumisnotpositive,yourprogramshouldprint:
Routerhasnoniceparts.
INPUTSAMPLE
3
3
-1
6
10
4
5
4
3
4
4
4
4
-5
4
2
3
4
OUTPUTSAMPLE
Thenicestpartofroute1isbetweenstops2and3
Thenicestpartofroute2ifbetweenstops3and9
Route3hasnoniceparts
2、求最长路径问题(NOI93):
对一个不存在回路的有向图,编程求出途经结点数最多的一条路径。
有向图存放在一个文本文件中,第0行为一个数字,为该图的结点总数N,其下还有N行,每行有N个非0即1的数字。
若第i行第j列的数字为1,则表示结点i到结点j存在由i指向j的边,否则该数为0。
3、删数问题的源程序:
输入数据:
一个高精度正整数N,所删除的数字个数S。
输出数据:
去掉的数字的位置和组成的新的正整数。
ProgramDelete_digit;
Varn:
string;{n是由键盘输入的高精度正整数}
s,a,b,c:
byte;{s是所要删除的数字的个数}
data:
array[1..200]of0..9;{记录删除的数字所在位置}
begin
readln(n);
readln(s);
fora:
=1tosdo
forb:
=1tolength(n)doifn[b]>n[b+1]then{贪心选择}
begin
delete(n,b,1);
data[a]:
=b+a-1;{记录所删除的数字的位置}
break;
end;
whilen[1]='0'dodelete(n,1,1);{将字符串首的若干个"0"去掉}
writeln(n);
fora:
=1tosdowriteln(data[a],'');
end.
4、最优乘车问题
输入数据:
输入文件INPUT.TXT。
文件的第行是一个数字M(1≤M≤100)表示开通了M条单向巴士线路,第2行是一个数字N(1 从第3行到第M+2行依次给出了第一条到第M条巴士线路的信息。 其中第i+2行给出的是第i条巴士线路的信息,从左至右依次按行行驶顺序给出了该线路上的所有站点,相邻两个站号之间用一个空格隔开。 输出数据: 输出文件是OUTPUT.TXT。 文件只有一行,为最少换车次数(在0,1,…,M-1中取值),0表示不需换车即可达到。 如果无法乘车达到S公园,则输出"NO"。 ProgramTravel; varm: 1..100;{m为开通的单向巴士线路数} n: 1..500;{n为车站总数} result: array[1..501]of-1..100;{到某车站的最少换车数} num: array[1..500,1..50]of1..500;{从某车站可达的所有车站序列} sum: array[1..500]of0..50;{从某车站可达的车站总数} check: array[1..500]ofBoolean;{某车站是否已扩展完} ProcedureInit; varf1: text; a,b,c,d: byte; data: array[1..100]of0..100; begin assign(f1,'input.txt'); reset(f1); readln(f1,m); readln(f1,n); result[501]: =100; fora: =1tomdo begin forb: =1to100dodata[b]: =0; b: =0; repeat inc(b); read(f1,data[b]); untileoln(f1); forc: =1tob-1do ford: =c+1tobdo begin inc(sum[data[c]]); num[data[c],sum[data[c]]]: =data[d]; end; end; end; ProcedureDone; varmin,a,b,c,total: integer; begin fillchar(result,sizeof(result),-1); result[1]: =0; forc: =1tosum[1]doresult[num[1,c]]: =0; b: =data[1,1]; repeat forc: =1tosum[b]do if(result[num[b,c]]=-1)thenresult[num[b,c]]: =result[b]+1; min: =501; forc: =1tondoif(result[c]<>-1)and(result[c] thenmin: =c; b: =min; untilresult[n]<>-1; writeln(result[n]);{到达S公园的最少换车次数} end; begin Init; end. 5、最佳游览路线问题 输入数据: 输入文件是INPUT.TXT。 文件的第一行是两个整数M和N,之间用一个空格符隔开,M表示有多少条旅游街(1≤M≤100),N表示有多少条林荫道(1≤N≤20000)。 接下里的M行依次给出了由北向南每条旅游街的分值信息。 每行有N-1个整数,依次表示了自西向东旅游街每一小段的分值。 同一行相邻两个数之间用一个空格隔开。 输出文件: 输出文件是OUTPUT.TXT。 文件只有一行,是一个整数,表示你的程序找到的最佳浏览路线的总分值。 ProgramTour; varm,n: integer;{M为旅游街数,N为林荫道数} data: array[1..20000]of-100..100;{data是由相邻两条林荫道所分} procedureInit;{隔的旅游街的最大分值} vara,b,c: integer; f1: text; begin assign(f1,'input.txt'); reset(f1); read(f1,m,n); fora: =1ton-1doread(f1,data[a]);{读取每一段旅游街的分值} fora: =2tomdo forb: =1ton-1do begin read(f1,c); ifc>data[b]thendata[b]: =c;{读取每一段旅游街的分值,并选择} end;{到目前位置所在列的最大分值记入数组data} close(f1); end; procedureDone; vara,sum,result,c: integer; f2: text; begin result: =0; sum: =0; a: =0; while(a begin inc(a);{从数组的第一个数据开始累加,将累加所} sum: =sum+data[a];{得到的最大分值记入result} ifsum>resultthenresult: =sum; ifsum<0thensum: =0;{若当前累加值为负数,则从当前状态起从新} end;{累加} assign(f2,'output.txt'); rewrite(f2); writeln(f2,result); close(f2); end; begin Init; Done; end.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 选自 名师 贪心 特点 应用