题意:n*m的网格,有一些障碍点不能通过,起点为(r1,c1),要求在经过T秒后,恰好在(r2,c2)。T秒内可以多次经过(r2,c2)但是第T秒时必须恰好在(r2,c2),1s移动一个单位长度,求有多少种满足条件的移动方案
由于T不超过15,一眼看过去dfs嘛
然后无脑dfs就华丽丽的TLE了
加一个剪枝:一个点到(r2,c2)的最少移动时间为 abs(r2-x)+abs(c2-y) ,如果第tt步到达的点(xx,yy) 不满足 tt+abs(r2-xx)+abs(c2-yy)<=t ,则第tt步到(xx,yy)完全没有必要进行dfs
然后卡过去了..
dfs代码:
const
walk:array[1..4,1..2] of longint=((1,0),(-1,0),(0,1),(0,-1));
var
n,m,t,ssx,ssy :longint;
ans,stx,sty :longint;
i,j :longint;
s :string;
map :array[0..110,0..110] of char;
procedure dfs(tt,x,y:longint);
var
k:longint;
tx,ty:longint;
begin
if tt=t then
begin
if (x=stx) and (y=sty) then inc(ans);exit;
end;
for k:=1 to 4 do
begin
tx:=x+walk[k,1]; ty:=y+walk[k,2];
if (tx>0) and (ty>0) and (tx<=n) and (ty<=m) then
if map[tx,ty]='.' then
if (tt+1+abs(stx-tx)+abs(sty-ty)<=t) then dfs(tt+1,tx,ty);
end;
end;
begin
readln(n,m,t);
for i:=1 to n do
begin
readln(s);
for j:=1 to m do map[i,j]:=s[j];
end;
readln(ssx,ssy,stx,sty);
dfs(0,ssx,ssy);
writeln(ans);
end.
好吧,其实正解是dp,f[i,j,k]表示第i秒到(j,k)的方案数
const
walk:array[1..4,1..2] of longint=((1,0),(-1,0),(0,1),(0,-1));
var
n,m,t,ssx,ssy,ty:longint;
stx,sty,tx :longint;
i,j,k,l :longint;
s :string;
map :array[0..110,0..110] of char;
f :array[0..20,0..110,0..110] of longint;
begin
readln(n,m,t);
for i:=1 to n do
begin
readln(s);
for j:=1 to m do map[i,j]:=s[j];
end;
readln(ssx,ssy,stx,sty);
f[0,ssx,ssy]:=1;
for i:=1 to t do
for j:=1 to n do
for k:=1 to m do
if map[j,k]<>'*' then
begin
for l:=1 to 4 do
begin
tx:=j-walk[l,1]; ty:=k-walk[l,2];
if (tx>0) and (ty>0) and (tx<=n) and (ty<=m) then
if map[tx,ty]='.' then inc(f[i,j,k],f[i-1,tx,ty]);
end;
end;
writeln(f[t,stx,sty]);
end.
——by Eirlys