迭代加深搜索-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上数据有误的可能,在此题的讨论区有很多已经提出来了

你可能感兴趣的:(DFS)