Codeforces Round #355 (Div. 2) Vanya and Treasure
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #355 (Div. 2) Vanya and Treasure相关的知识,希望对你有一定的参考价值。
这是一道很显然的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的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #355 (Div. 2)
Codeforces Round #355 (Div. 2)
Codeforces Round #355 (Div. 2) D. Vanya and Treasure 分治暴力
Codeforces Round #355 (Div. 2) Vanya and Label