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

posted on 2011-03-30 22:46  oa414  阅读(489)  评论(0编辑  收藏  举报

导航