$DP $, tree-like array.
Obviously this is a $dag$ on the $dp$, because the side too much, the violence $dp$ will time out, need to optimize.
For example, to calculate $dp[x][y]$, you can divide the area into four blocks, $DP [x][y]$ the minimum value in four blocks, and each block maintains a minimum value with a two-dimensional tree array.
Each extension requires a new tree array, because each initialization of the tree array will time out, so you can open an extra array to record the number of times each point is updated.
#pragmaComment (linker, "/stack:1024000000,1024000000")#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<vector>#include<map>#include<Set>#include<queue>#include<stack>#include<iostream>using namespaceStd;typedefLong LongLL;Const DoublePi=acos (-1.0), eps=1e-6;voidFile () {freopen ("D:\\in.txt","R", stdin); Freopen ("D:\\out.txt","W", stdout);} Template<classT>inlinevoidRead (T &x) { CharC=getchar (); x=0; while(!isdigit (c)) c=GetChar (); while(IsDigit (c)) {x=x*Ten+c-'0'; C=GetChar ();}}Const intinf=0x7FFFFFFF;Const intmaxn=310;intn,m,p,a[maxn][maxn],c[4][maxn][maxn],d[4][maxn][maxn],dp[maxn][maxn];vector<int>v[maxn*MAXN];intLowbit (intx) {returnx& (-x);}int Get(intOpintHintXinty) { intres=INF; for(intI=x;i>0; i=i-lowbit (i)) for(intJ=y;j>0; j=j-Lowbit (j))if(d[op][i][j]==h) res=min (res,c[op][i][j]); returnRes;}voidUpdateintOpintHintXintYintv) { for(inti=x;i<=n;i=i+lowbit (i)) for(intj=y;j<=m;j=j+Lowbit (j)) { if(d[op][i][j]!=h) c[op][i][j]=INF; D[OP][I][J]=h; c[op][i][j]=min (c[op][i][j],v); }}intMain () {scanf ("%d%d%d",&n,&m,&p); for(intI=0; i<n;i++) for(intj=0; j<m;j++) {scanf ("%d",&A[i][j]); V[a[i][j]].push_back (i*m+j); } for(intk=0;k<4; k++) for(intI=1; i<=n;i++) for(intj=1; j<=m;j++) C[k][i][j]=inf,d[k][i][k]=- -; for(intI=0; i<v[1].size (); i++) dp[v[1][i]/m+1[(v[1][I]%M) +1]=v[1][i]/m+v[1][i]%m; for(intI=2; i<=p;i++) { for(intj=0; j<v[i-1].size (); j + +) { intr=v[i-1][j]/m,c=v[i-1][j]%m; r++; C++; Update (0, I-1, r,c,dp[r][c]-r-c); Update (1, I-1, r,m-c+1, dp[r][c]-r+c); Update (2, I-1, n-r+1, c,dp[r][c]+r-c); Update (3, I-1, n-r+1, m-c+1, dp[r][c]+r+c); } for(intj=0; J<v[i].size (); j + +) { intr=v[i][j]/m,c=v[i][j]%m; r++; C + +; dp[r][c]=INF; if(Get(0, I-1, r,c)!=inf) dp[r][c]=min (Dp[r][c],Get(0, I-1, R,c) +r+c); if(Get(1, I-1, r,m-c+1)!=inf) Dp[r][c]=min (Dp[r][c],Get(1, I-1, r,m-c+1) +r-c); if(Get(2, I-1, n-r+1, c)!=inf) Dp[r][c]=min (Dp[r][c],Get(2, I-1, n-r+1, c)-r+c); if(Get(3, I-1, n-r+1, m-c+1)!=inf) Dp[r][c]=min (Dp[r][c],Get(3, I-1, n-r+1, m-c+1)-r-c); } } intans=0; for(intI=0; i<n;i++) for(intj=0; j<m;j++) if(a[i][j]==p) ans=dp[i+1][j+1]; printf ("%d\n", ans); return 0;}
Codeforces 677D Vanya and Treasure