This is a very obvious DP topic, state transfer in the topic is also very direct, that is, from k-1 to K, however, if COUNT[K-1]*CNT[K], then the complexity of time will be very large, the original complexity should be O (p*n*n*m*m), with DP words will be very tle, read Daniel's explanation after is to use DP at P<SQRT (MN), then use BFS if P>SQRT (nm), so that the time complexity can be calculated using the averaging analysis (I'm going to write a blog post on the averaging analysis).
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue& GT, #include <cmath> #include <algorithm> #define X first#define Y second#define MP Make_pair#define pair pair& Lt;int,pair<int,int> >using namespace Std;const int inf=99999999;const int maxn=305;const int MAXP=MAXN*MAXN; const int Dx[4]={0,1,0,-1},dy[4]={-1,0,1,0};int n,m,p,a[maxn][maxn],dp[maxn][maxn];int d[maxn][maxn];struct Node{ int x, y; Node (int x,int y) {this->x=x;this->y=y;}}; Vector<pair > Lst;vector<node> g[maxp];bool in_range (int x,int y) {if (x>=1&&x<=n&&y >=1&&Y<=M) return True;return false;} int main () {for (Int. i=0;i<maxn;i++) for (int j=0;j<maxn;j++) dp[i][j]=inf;scanf ("%d%d%d", &n,&m,&p); for (int i=1;i<=n;i++) {for (int j=1;j<=m;j++) {scanf ("%d", &a[i][j]); G[a[i][j]].push_back (Node (i,j)); if (a[i][j]==1) {dp[i][j]= (i-1) + (j-1);}}} for (int k=2;k<=p;k++) {if (G[k].size () *g[k-1].Size () <n*m) {for (int i=0;i<g[k].size (); i++) {node& p1=g[k][i];for (int j=0;j<g[k-1].size (); j + +) {Node & P2=g[k-1][j];int Dist=abs (p1.x-p2.x) +abs (p1.y-p2.y);DP [P1.x][p1.y]=min (Dp[p1.x][p1.y],dp[p2.x][p2.y]+dist) ;}}} else{for (int i=0;i<=n;i++) for (int j=0;j<=m;j++) D[i][j]=-1;queue<pair > Que;while (!que.empty ()) Que.pop ( ); Lst.clear (); for (int i=0;i<g[k-1].size (); i++) {int X=g[k-1][i].x;int Y=g[k-1][i].y;lst.push_back (MP (Dp[x][y), MP (x, y));} int cnt (0), sum (G[k].size ()), Sort (Lst.begin (), Lst.end ()), for (int i=0;i<lst.size (); i++) {Que.push (lst[i]);d [lst[ I]. Y.x][lst[i]. Y.y]=lst[i]. X;} while (!que.empty ()) {Pair temp=que.front (); Que.pop (), for (int i=0;i<4;i++) {int tx=temp. Y.x+dx[i];int ty=temp. Y.y+dy[i];if (In_range (tx,ty)) {if (d[tx][ty]==-1| | D[tx][ty]>temp. x+1) {d[tx][ty]=temp. X+1;que.push (MP (temp. X+1,MP (Tx,ty))); if (a[tx][ty]==k) {dp[tx][ty]=min (dp[tx][ty],temp. x+1);}}}}}} printf ("%d\n", Dp[g[p][0].x][g[p][0].y]); return 0;}
Codeforces Round #355 (Div. 2) Vanya and Treasure