poj 3460 bookstore

分析:第二道IDA*题目。

那个估价函数确实不好想,不过做了这道题目之后应该对IDA*的应用范围有了更为明确地了解。IDA*应用于搜索树的深度比较小,但是每一层扩展出来的节点呈指数增长,这样的话BFS空间上受不了,DFS时间上受不了。于是想到用迭代加深搜索,即ID搜索。但是普通的ID搜索并不能快很多,于是有了IDA*搜索。这当中最难的就是A*中的估价函数的设计,这一点需要充分利用题目中的条件,保证估价函数小于等于实际最优值,而且要尽量接近最优值。这样的话会快很多。

代码:

type

  arr=array[0..15] of integer;

var

  a,b:arr;

  i,j,k,n,t,step,ans:longint;

  vv:boolean;



function ok:boolean;

var

  i:longint;

begin

  for i:=1 to n do

    if a[i]<>i then exit(false);

  exit(true);

end;



function h:longint;

var

  i:longint;

begin

  h:=0;

  for i:=1 to n-1 do

    if a[i+1]<>a[i]+1 then

      inc(h);

  h:=(h-1)div 3+1;

end;



procedure IDAstar(deep:longint);

var

  f,i,j,k,l,s:longint;

  c:arr;

begin

  if ok then

    begin

      vv:=true;

      ans:=deep;

      exit;

    end;

  f:=h;

  if deep+f>step then exit;

  for i:=1 to n-1 do

    for j:=1 to n-i do

      for k:=i+j to n do

        begin

          c:=a;

          s:=i;

          for l:=k-j+1 to k do

            begin

              a[l]:=c[s];

              inc(s);

            end;

          for l:=1 to k-j+1-i do

            begin

              a[l+i-1]:=c[l+i-1+j];

            end;

          IDAstar(deep+1);

          if vv then exit;

          a:=c;

        end;

end;



begin

  readln(t);

  while t>0 do

    begin

      dec(t);

      readln(n);

      for i:=1 to n do read(b[i]);

      vv:=false;

      ans:=maxlongint;

      for step:=1 to 4 do

        begin

          a:=b;

          IDAstar(0);

          if vv then break;

        end;

      if not vv then writeln('5 or more')

      else writeln(ans);

    end;

end.

  

注意的是迭代的第一个解肯定是最优解,而且找到解之后要及时跳出,不能再继续搜索了。

你可能感兴趣的:(store)