10.18 取数 2434

题目

这里写图片描述

题解

就是一个深索,从每个点出发找最长等差数列就可以了,但是直接搜肯定会爆,所以考虑记忆化
刚开始想的是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.

我记得我写对了,但是忘记提交到网络上,于是不得不重写

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值