您的位置:首页 > 其它

老曹骑士

2016-06-27 20:40 375 查看

老曹骑士

Time Limits: 1000 ms Memory Limits: 65536 KB

Description

  我们的主角——老曹陨落于国际象棋棋盘,成为了一位老曹骑士,于是,他开始走“日”字型路线。 

  在一张N*N的棋盘上,有K只邪恶的河蟹,骑士曹现在要消灭这些河蟹。

  要求曹从任意一只河蟹出发,通过他“日”字型的跳跃,到达这K个点至少一次,并最终回到起点。

  现在已知棋盘的大小N,和这K只河蟹的位置(棋盘的左上角坐标记为(1,1),右下角坐标记为(N,N))。

  询问:曹最少要跳多少步。

Input

  第一行:两个整数,N,K(4<=N<=20,1<=K<=10)

  接下来K行:每行两个整数X,Y,表示河蟹所在位置。

Output

  一个整数,表示曹所需要条的最少步数。

Sample Input

8 3
2 3
4 5
6 7


Sample Output

12


题目描述

这道题的意思不多说了吧:

给出n只河蟹的坐标,让你踩死它们并回到原点。

其中河蟹大脑皮层的组织运动的神经中枢出了极大的问题致使他们只能被禁锢在一个格子中无法动弹,只能眼睁睁地看着老曹踩死自己。

当老曹沦落(据说是因过度腐败被抓)到棋盘是,他不是在(1,1)上,而是开外挂在一开始选择一个河蟹踩死它,当时已走步数为0,然后再慢慢地以“日”字走法踩其它河蟹最后回到一开始落下的地方,当然,老曹不能跳出棋盘,因为这意味着dying。

解题思路

好像只有我显得那么与众不同:我竟然用了DP

好吧,我设F[i,j,k,x]表示从第i只河蟹出发,已经才死了j只河蟹,最后到达了第k只河蟹,x为死了的河蟹的状态压缩。

设Distance{i,j}表示第i只河蟹到第j只河蟹的距离。

很好理解Fi,j,k,x=MinFi,j−1,l,x xor 2l−1+Distancei,j (2l−1 and x>0 ; l<>i)F_{i,j,k,x}=^{Min}{F_{i,j-1,l,x\ xor\ 2^{l-1}}+Distance_{i,j}}\ \ \ \ \ \ (2^{l-1}\ and\ x>0\ \ ;\ \ \ l<>i)

其中Fi,1,i,2i−1=0F_{i,1,i,2^{i-1}}=0

MinFi,n,j,2n−1+Distancei,j^{Min}{F_{i,n,j,2^n-1}+Distance_{i,j}}便是答案

const
fx:array[1..8,1..2]of shortint=((1,2),(1,-2),(-1,2),(-1,-2),(2,1),(2,-1),(-2,1),(-2,-1));

var
data:array[1..400,1..3]of integer;
bz:array[1..20,1..20]of boolean;
loca:array[1..10,1..2]of longint;
f:array[1..10,1..10,1..10,1..1023]of longint;
g:array[1..10,1..10]of longint;
n,k,i,j,l,ans,h,t,o,s:longint;

{求两只河蟹的距离}
function Get_Steps(x1,y1,x2,y2:longint):longint;
var x,y,xx,yy,s:longint;
begin
fillchar(bz,sizeof(bz),true);
data[1,1]:=x1;data[1,2]:=y1;data[1,3]:=0;
bz[x1,y1]:=false;h:=0;t:=1;
while h<t do
begin
inc(h);
x:=data[h,1];y:=data[h,2];s:=data[h,3];
for o:=1 to 8 do
begin
xx:=x+fx[o,1];yy:=y+fx[o,2];
if(xx<1)or(xx>n)then continue;
if(yy<1)or(yy>n)then continue;
if(xx=x2)and(yy=y2)then exit(s+1);
if bz[xx,yy] then
begin
bz[xx,yy]:=false;inc(t);
data[t,1]:=xx;data[t,2]:=yy;data[t,3]:=s+1;
end;
end;
end;
end;

function min(p,q:longint):longint;
begin if p<q then exit(p) else exit(q);end;

{Main}
begin
read(n,k);
for i:=1 to k do read(loca[i,1],loca[i,2]);
for i:=1 to k-1 do
for j:=i+1 to k do
begin g[i,j]:=Get_Steps(loca[i,1],loca[i,2],loca[j,1],loca[j,2]);g[j,i]:=g[i,j];end;{求两两河蟹的距离}
fillchar(f,sizeof(f),$7f);
for i:=1 to k do f[i,1,i,1<<(i-1)]:=0;
for s:=1 to k do
for i:=2 to k do
for j:=1 to k do
for l:=1 to 1<<k-1 do
if l and(1<<(j-1))>0 then
for o:=1 to k do
if o<>j then
if l and(1<<(o-1))>0 then f[s,i,j,l]:=min(f[s,i,j,l],f[s,i-1,o,l xor (1<<(j-1))]+g[o,j]);
ans:=maxlongint;
for i:=1 to k do
for j:=1 to k do ans:=min(ans,f[i,k,j,1<<k-1]+g[i,j]);
writeln(ans);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: