MY*****

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.

  

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

posted on 2011-10-20 07:54  reflec94  阅读(321)  评论(0编辑  收藏  举报

导航