迭代加深搜索-DFSID:埃及分数
迭代加深搜索看似很复杂,但是实际上并不难。我看了USACO的这篇课文:http://www.oiers.cn/usaco%20training/11-401.asp.htm就明白了,具体的网上资料不少,就不罗嗦了。但一直没有通过题目来练习。这几天终于把埃及分数弄懂了。
埃及分数是经典的DFSID例题,不知道出处,我的程序如下:
var maxnumber,maxdep:int64; //因为好像要搜到很小的分母,所以很多地方都要int64 ans,bestans:Array[0..10000] of int64; flag:boolean; a,b,x,y:int64; i:longint; function max(a,b:int64):int64; begin if a>b then exit(a) else exit(b); end; function min(a,b:int64):int64; begin if a>b then exit(b) else exit(a); end; procedure dfs(dep:longint); var xx,yy:int64; minnum,maxnum:longint; i:longint; begin minnum:=max(ans[dep-1]+1,y div x); maxnum:=min(y*(maxdep-dep+1) div x,maxnumber-1);//上下界剪枝 xx:=x; yy:=y; for i:=minnum to maxnum do begin x:=xx; y:=yy; ans[dep]:=i; x:=x*i-y; if x<0 then continue; y:=y*i;//用整数来代替浮点数减少误差并加速 if dep<maxdep then dfs(dep+1) else if (i<maxnumber)and(x=0) then//保存最优解 begin flag:=true; maxnumber:=i;//maxnumber表示当前最小的分母 bestans:=ans; end; end; end; begin maxnumber:=9999999999; readln(a,b); while not flag do begin inc(maxdep);//迭代加深 x:=a; y:=b; dfs(1); end; for i:=1 to maxdep-1 do write(bestans[i],' '); writeln(bestans[maxdep]); end.
题目链接:http://www.rqnoj.cn/Problem_240.html
做题时主要参考:http://wysoviet.blog.hexun.com/22540073_d.html
http://www.rqnoj.cn/Discuss_Show.asp?DID=1750
我的程序在RQNOJ上只能得80,不排除RQ上数据有误的可能,在此题的讨论区有很多已经提出来了