标签:
这是一道很显然的DP题目,状态转移在题目中也很直接,就是从k-1到k,然而如果count[k-1]*cnt[k],那么时间复杂度就会很大,本来的复杂度应该是O(p*n*n*m*m),用DP的话会很TLE,看了大牛的解释后,是在p<sqrt(mn)时候用DP,之后如果p>sqrt(nm)的话就用BFS,这样用均摊分析可以计算其时间复杂度(后边我打算写一篇关于均摊分析的博文)。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <cmath>
#include <algorithm>
#define X first
#define Y second
#define mp make_pair
#define Pair pair<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
标签:
原文地址:http://www.cnblogs.com/northsnow95/p/5565548.html