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