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.
注意的是迭代的第一个解肯定是最优解,而且找到解之后要及时跳出,不能再继续搜索了。