欢迎来到天天文库
浏览记录
ID:35465559
大小:73.28 KB
页数:14页
时间:2019-03-25
《贪心算法的应用》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、在求最优解问题的过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解,这种求解方法就是贪心算法。从贪心算法的定义可以看出,贪心法并不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。我们看看下面的例子例1均分纸牌(NOIP2002tg)[问题描述]冇N堆纸牌,编号分别为1,2,...,No每堆上冇若干张,但纸牌总数必为N的倍数。可以在任一堆上取若干张纸牌,然后移动。移牌规则为:在编号为1堆上取的纸牌,只能移到编号为2
2、的堆上;在编号为N的堆上取的纸牌,只能移到编号为N-1的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。例如N=4,4堆纸牌数分别为:①9②8③17④6移动3次可达到目的:从③取4张牌放到④(981310)从③取3张牌放到②(9111010)->从②取1张牌放到①(10101010)。[输入]:键盘输入文件名。文件格式:N(N堆纸牌,1v=Nv=100)A1A2...An(N堆纸牌,每堆纸牌初始数,lv=Ai<=10000)[输出]:输出至屏幕。格式为:所有堆均达到相等吋的最少移
3、动次数。[输入输出样例]a.in:498176屏慕显示:3算法分析:设a[i]为第i堆纸牌的张数(0v=iv=n),v为均分后每堆纸牌的张数,s为最小移到次数。我们用贪心法,按照从左到右的顺序移动纸牌。如第i堆(Ovivn)的纸牌数a[i]不等于平均值,则移动一次(即s加1),分两种情况移动:(1)若a[i]>v,则将a[i]-v张纸牌从第I堆移动到第1+1堆;(2)若a[i]4、]:=a[l+1]+a[l]-v:在从第i+i堆中取出纸牌补充第i堆的过程中,可能会出现第i+1堆的纸牌数小于零(a[i+1]+a[i]・vvO)的情况。如n=3,三堆纸牌数为(1,2,27)这时v=10,为了使第一堆数为10,要从第二堆移9张纸牌到第一堆,而第二堆只有2张纸牌可移,这是不是意味着刚才使用的贪心法是错误的呢?我们继续按规则分析移牌过程,从第二堆移出9张到第一堆后,第一堆冇10张纸牌,第二堆剩下・7张纸牌,再从第三堆移动17张到第二堆,刚好三堆纸牌数都是10,最后结果是对的,从第二堆移出的牌都可以从第三堆得到。我们在移动过程中,只是改变5、了移动的顺序,而移动的次数不变,因此此题使用贪心法是可行的。源程序:vari,n,s:integer;v:longint;a:array[1..100]oflongint;f:text;fil:string;beginreadln(fil);assign(f,fil);reset(f);readln(f,n);v:=O;fori:=1tondobeginread(f,a[i]);inc(v,a[i]);end;v:=vdivn;{每堆牌的平均数}fori:=1ton-1doifa[i]ovthen{贪心选择}begininc(s);{移牌步数计数}a6、[i+1]:=a[i+1]+a[i]-v;{使第i堆牌数为v}end;{then}writeln(s);end.利用贪心算法解题,需耍解决两个问题:一是问题是否适合用贪心法求解。我们看一个找币的例子,如果一个货币系统有3种币值,而值分别为一角、五分和一分,求最小找币数吋,可以用贪心法求解;如果将这三种币值改为一角一分、五分和一分,就不能使用贪心法求解。用贪心法解题很方便,但它的适用范圉很小,判断一个问题是否适合用贪心法求解,目前还没冇一个通用的方法,在信息学竞赛中,需要凭个人的经验來判断何时该使用贪心算法。二是确定了可以用贪心算法之后,如何选择一个贪7、心标准,才能保证得到问题的最优解。在选择贪心标准时,我们要对所选的贪心标准进行验证才能使用,不要被表而上看似正确的贪心标准所迷惑,如下而的列子。例2(NOIP1998tg)设有n个正整数,将他们连接成一排,组成一个故大的多位整数。例如:n=3时,3个整数13,312,343,连成的最大整数为:34331213又如:n=4时,4个整数7,13,4,246连接成的最大整数为7424613输入:NN个数输出:连接成的多位数算法分析:此题很容易想到使用贪心法,在考试时冇很多同学把整数按从大到小的顺序连接起來,测试题目的例子也都符合,但最后测试的结果却不全对。8、按这种贪心标准,我们很容易找到反例:12,121应该组成12121而非12112,那么是不是相互包含的时候就
4、]:=a[l+1]+a[l]-v:在从第i+i堆中取出纸牌补充第i堆的过程中,可能会出现第i+1堆的纸牌数小于零(a[i+1]+a[i]・vvO)的情况。如n=3,三堆纸牌数为(1,2,27)这时v=10,为了使第一堆数为10,要从第二堆移9张纸牌到第一堆,而第二堆只有2张纸牌可移,这是不是意味着刚才使用的贪心法是错误的呢?我们继续按规则分析移牌过程,从第二堆移出9张到第一堆后,第一堆冇10张纸牌,第二堆剩下・7张纸牌,再从第三堆移动17张到第二堆,刚好三堆纸牌数都是10,最后结果是对的,从第二堆移出的牌都可以从第三堆得到。我们在移动过程中,只是改变
5、了移动的顺序,而移动的次数不变,因此此题使用贪心法是可行的。源程序:vari,n,s:integer;v:longint;a:array[1..100]oflongint;f:text;fil:string;beginreadln(fil);assign(f,fil);reset(f);readln(f,n);v:=O;fori:=1tondobeginread(f,a[i]);inc(v,a[i]);end;v:=vdivn;{每堆牌的平均数}fori:=1ton-1doifa[i]ovthen{贪心选择}begininc(s);{移牌步数计数}a
6、[i+1]:=a[i+1]+a[i]-v;{使第i堆牌数为v}end;{then}writeln(s);end.利用贪心算法解题,需耍解决两个问题:一是问题是否适合用贪心法求解。我们看一个找币的例子,如果一个货币系统有3种币值,而值分别为一角、五分和一分,求最小找币数吋,可以用贪心法求解;如果将这三种币值改为一角一分、五分和一分,就不能使用贪心法求解。用贪心法解题很方便,但它的适用范圉很小,判断一个问题是否适合用贪心法求解,目前还没冇一个通用的方法,在信息学竞赛中,需要凭个人的经验來判断何时该使用贪心算法。二是确定了可以用贪心算法之后,如何选择一个贪
7、心标准,才能保证得到问题的最优解。在选择贪心标准时,我们要对所选的贪心标准进行验证才能使用,不要被表而上看似正确的贪心标准所迷惑,如下而的列子。例2(NOIP1998tg)设有n个正整数,将他们连接成一排,组成一个故大的多位整数。例如:n=3时,3个整数13,312,343,连成的最大整数为:34331213又如:n=4时,4个整数7,13,4,246连接成的最大整数为7424613输入:NN个数输出:连接成的多位数算法分析:此题很容易想到使用贪心法,在考试时冇很多同学把整数按从大到小的顺序连接起來,测试题目的例子也都符合,但最后测试的结果却不全对。
8、按这种贪心标准,我们很容易找到反例:12,121应该组成12121而非12112,那么是不是相互包含的时候就
此文档下载收益归作者所有