zoukankan      html  css  js  c++  java
  • codeforces 677D

    题解:

    这东西就是分层DP

    考虑dp ( i , j )表示到位置( i , j )的最短长度

    然后可以枚举上一次的位置转移过来

    这样单次转移复杂度和两层中点的数量有关

    这样复杂度显然是O((nm)^2)的,爆炸

    考虑另一种暴力,每次转移时bfs,这样单次转移复杂度O(nm)

    考虑根号分治,当两层点数乘积>nm时用bfs,这种情况不会超过sqrt(nm)个

    然后两层点数乘积<nm时,考虑暴力DP转移

    复杂度O(nmsqrt(nm))

      1 #include<bits/stdc++.h>
      2 #define maxn 305
      3 #define pii pair<int,int>
      4 #define mp(a,b) make_pair(a,b)
      5 using namespace std;
      6 int n,m,p;
      7 vector<pii> v[maxn*maxn];
      8 struct node
      9 {
     10     pii pos;
     11     int dis;
     12     node(){}
     13     node(pii P,int D){pos=P;dis=D;}
     14 };
     15 bool operator < (node a,node b)
     16 {
     17     return a.dis<b.dis;
     18 }
     19 int ans[maxn][maxn],dis[maxn][maxn];
     20 bool vis[maxn][maxn];
     21 int Ax,Ay;
     22 int main()
     23 {
     24     scanf("%d%d%d",&n,&m,&p);
     25     for(int i=1;i<=n;++i)
     26         for(int j=1;j<=m;++j)
     27         {
     28             int x;
     29             scanf("%d",&x);
     30             v[x].push_back(mp(i,j));
     31             if(x==p)Ax=i,Ay=j;
     32         }
     33     memset(ans,127/2,sizeof(ans));
     34     for(int i=0;i<v[1].size();++i)
     35     {
     36         int x=v[1][i].first,y=v[1][i].second;
     37         ans[x][y]=abs(x-1)+abs(y-1);
     38     }
     39     for(int i=2;i<=p;++i)
     40     {
     41         if(v[i-1].size()*v[i].size()<n*m)
     42         {
     43             for(int j=0;j<v[i].size();++j)
     44             {
     45                 for(int k=0;k<v[i-1].size();++k)
     46                 {
     47                     int x=v[i][j].first,y=v[i][j].second;
     48                     int u=v[i-1][k].first,w=v[i-1][k].second;
     49                     ans[x][y]=min(ans[x][y],ans[u][w]+abs(x-u)+abs(y-w));
     50                 }
     51             }
     52         }
     53         else
     54         {
     55             const int dx[]={-1,0,1,0};
     56             const int dy[]={0,-1,0,1};
     57             memset(dis,0,sizeof(dis));
     58             memset(vis,0,sizeof(vis));
     59             vector<node> t;
     60             queue<node> q1,q2;
     61             for(int j=0;j<v[i-1].size();++j)t.push_back(node(v[i-1][j],ans[v[i-1][j].first][v[i-1][j].second]));
     62             sort(t.begin(),t.end());
     63             for(int j=0;j<t.size();++j)
     64             {
     65                 q2.push(t[j]);
     66                 int x=t[j].pos.first,y=t[j].pos.second;
     67                 vis[x][y]=1;
     68                 dis[x][y]=t[j].dis;
     69             }
     70             while(!q1.empty()||!q2.empty())
     71             {
     72                 node u;
     73                 if(q1.empty())u=q2.front(),q2.pop();
     74                 else if(q2.empty())u=q1.front(),q1.pop();
     75                 else
     76                 {
     77                     if(q1.front().dis<q2.front().dis)u=q1.front(),q1.pop();
     78                     else u=q2.front(),q2.pop();
     79                 }
     80                 int x=u.pos.first,y=u.pos.second;
     81                 for(int k=0;k<4;++k)
     82                 {
     83                     int nx=x+dx[k],ny=y+dy[k],nd=u.dis+1;
     84                     if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&(!vis[nx][ny]))
     85                     {
     86                         vis[nx][ny]=1;
     87                         dis[nx][ny]=nd;
     88                         q1.push(node(mp(nx,ny),nd));
     89                     }
     90                 }
     91             }
     92             for(int j=0;j<v[i].size();++j)
     93             {
     94                 int x=v[i][j].first,y=v[i][j].second;
     95                 ans[x][y]=dis[x][y]; 
     96             } 
     97         }
     98     }
     99     printf("%d
    ",ans[Ax][Ay]);
    100     return 0;
    101 }
    View Code
  • 相关阅读:
    合并报表优化记录
    如何在后台代码中执行原生sql?
    eclipse从数据库逆向生成Hibernate实体类
    用Eclipse进行远程Debug代码
    hibernate自动生成数据库表
    hibernate自动生成数据库表
    php通过UNIX源码编译安装
    php设置方法
    php其他配制选项
    终于做出了目录认证!
  • 原文地址:https://www.cnblogs.com/uuzlove/p/10548587.html
Copyright © 2011-2022 走看看