uva11163 Jaguar King

这道题乍一看暴力都不知道怎么写,可是我们一旦把它由一列数转换为宽为4的二维图形时做法就明了了。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

转换为二维时就是

1    2    3      4

5    6    7     8

9    10   11   12

13  14   15   16

可以看出5可以跳到1,9,6,8;6可以跳到2,5,7,10;其他的也是如此,可以走到它的上下左右四个格子。

暴力搜索肯定会超时,那么,如何优化呢?

题目要求我们将一个状态转换到另一个状态,所以我们就可以很容易的想到用估价函数来优化。

因为豹王可以从一行的最左边跳到最右边,我们便不可以用曼哈顿距离来求两点间的距离而要用连边求最短路来得到。

那么估价函数h=Σg[i,a[i]](g[i,j]代表从第i个格子到第j个格子的距离)

程序如下:

{$inline on}
const
go:array[0..3,1..4]of longint=((-3,-1,4,-4),(1,3,4,-4),(1,-1,4,-4),(1,-1,4,-4));
var
a,num:array[1..40] of longint;
g:array[-5..45,-5..45]of longint;
tot,pos,ans,n,m,i,j,k:longint;
function min (a,b:longint):longint;inline;
begin
if a<B then exit(a) else exit(b);
end;


procedure ycl;inline;
var
i,j,k:longint;
begin
fillchar(g,sizeof(g),$3f);
for i:=1 to 40 do
  for j:=1 to 4 do
        g[i,i+go[i mod 4,j]]:=1;
for i:=1 to 40 do
  g[i,i]:=0;
for k:=1 to 40 do
  for i:=1 to 40 do
      for j:=1 to 40 do
           g[i,j]:=min(g[i,j],g[i,k]+g[k,j]);
end;//求最短路;


function dfs(deep,gu,now,last:longint):boolean;
var
kk,x,i,j,k:longint;
begin
if gu<=0 then
  exit(true);
if deep+gu>ans then
  exit(false);
for i:=1 to 4 do
  begin
    x:=now+go[now mod 4,i];
    if (x<>last)and(x>0)and(x<=n) then
      begin
        kk:=gu-g[x,a[x]]+g[now,a[x]];
        if kk<0 then
          exit(true);
        a[now]:=a[x];  a[x]:=1;
        if dfs(deep+1,kk,x,now) then
          exit(true);
        a[x]:=a[now]; a[now]:=1;
      end;
  end;
exit(false);
end;

procedure main;inline;
var
i,j,k:longint;
begin
j:=0;
for i:=1 to n do
    j:=j+g[i,a[i]];
j:=j-g[pos,1];
writeln('Set ',tot,':');
for ans:=0 to maxlongint do
  if dfs(0,j,pos,-1) then
    begin
      writeln(ans);
      exit;
    end;
end;


begin
ycl;
tot:=0;
while true do
  begin
    inc(tot);
    readln(n);
    if n=0 then
      exit;
    for i:=1 to n do
      begin
        read(a[i]);
        if a[i]=1 then
          pos:=i;
      end;
    main;
  end;
end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值