题目
题解
就是一个深索,从每个点出发找最长等差数列就可以了,但是直接搜肯定会爆,所以考虑记忆化
刚开始想的是c[i,j,k]表示点i,j的最长等差数列长度为k,这样记录虽然答案正确,但是内存会爆
所以这时候该题解登场了——c[i,j,k]表示点i,j向第k方向(共4个方向)走的最长等差数列长度,很显然一下子少了很多无用的内存,而且每一种状态都能表示,因为每个方向只可能有一个差
然后就是广搜了
代码
这个是我的写法
const
dx:array[1..4]of integer=(1,-1,0,0);
dy:array[1..4]of integer=(0,0,-1,1);
var
n,m,i,j,k,max:longint;
a,b:array[0..101,0..101]of longint;
c:array[0..101,0..101,0..4000]of longint;
procedure dfs(x,y,t:longint);
var
i,j,k:longint;
begin
for i:=1 to 4 do
if (a[x+dx[i],y+dy[i]]-a[x,y]=t)and(x+dx[i]>0)and(x+dx[i]<=n)
and(y+dy[i]>0)and(y+dy[i]<=m)and(b[x+dx[i],y+dy[i]]=0) then
begin
if (c[x,y,t]+1>c[x+dx[i],y+dy[i],t]) then
begin
b[x+dx[i],y+dy[i]]:=1;
c[x+dx[i],y+dy[i],t]:=c[x,y,t]+1;
dfs(x+dx[i],y+dy[i],t);
b[x+dx[i],y+dy[i]]:=0;
end;
end;
end;
begin
readln(n,m);
for i:=1 to n do
for j:=1 to m do
begin
read(a[i,j]);
for k:=1 to 4000 do
c[i,j,k]:=1;
end;
for i:=1 to n do
for j:=1 to m do
for k:=1 to 4 do
if (i+dx[k]>0)and(i+dx[k]<=n)and(j+dy[k]>0)and(j+dy[k]<=m)
and(a[i+dx[k],j+dy[k]]>a[i,j])
and(c[i,j,a[i+dx[k],j+dy[k]]-a[i,j]]=1) then
begin
b[i,j]:=1;
c[i+dx[k],j+dy[k],a[i+dx[k],j+dy[k]]-a[i,j]]:=2;
dfs(i+dx[k],j+dy[k],a[i+dx[k],j+dy[k]]-a[i,j]);
b[i,j]:=0;
end;
for i:=1 to n do
for j:=1 to m do
for k:=1 to 4000 do
if c[i,j,k]>max then max:=c[i,j,k];
writeln(max);
end.
我记得我写对了,但是忘记提交到网络上,于是不得不重写