zoukankan      html  css  js  c++  java
  • codeforce 677D Vanya and Treasure

    原题地址:http://codeforces.com/problemset/problem/677/D

    题意

    题解

    直接的DP是n2m2的复杂度,据题解说通过bfs来转移可以实现n*m*sqrt(n*m)……

    #include<bits/stdc++.h>
    
    #define clr(x,y) memset((x),(y),sizeof(x))
    
    using namespace std;
    typedef long long LL;
    
    const int maxn=300;
    
    struct Cood
    {
        int x;
        int y;
    };
    
    vector <Cood> G[maxn*maxn+5];
    queue<Cood> Q;
    
    int dx[]={0,0,-1,1};
    int dy[]={1,-1,0,0};
    int dp[maxn+5][maxn+5];
    int temp[maxn+5][maxn+5];
    bool book[maxn+5][maxn+5];
    
    int main(void)
    {
        #ifdef ex
        freopen ("../in.txt","r",stdin);
        //freopen ("../out.txt","w",stdout);
        #endif
    
        int n,m,p;
        scanf("%d%d%d",&n,&m,&p);
    
        clr(dp,127);
        int a;
        for (int i=1;i<=n;++i)
        {
            for (int j=1;j<=m;++j)
            {
                scanf("%d",&a);
                G[a].push_back((Cood){i,j}); /*****/
                if (a==1) dp[i][j]=i+j-2;
            }
        }
    
        int k=sqrt(n*m);
    
        for (int i=2;i<=p;++i)
        {
            if (G[i].size()<k)
            {
                for (auto g1:G[i])
                {
                    for (auto g2:G[i-1])
                    {
                        dp[g1.x][g1.y]=min(dp[g1.x][g1.y],dp[g2.x][g2.y]+abs(g1.x-g2.x)+abs(g1.y-g2.y));
                    }
                }
            }
    
            else
            {
                clr(temp,127); //全部初始化为MAX_INT
                clr(book,0);
                for (auto g:G[i-1])
                {
                    Q.push(g);
                    temp[g.x][g.y]=dp[g.x][g.y];
                }
    
                while (!Q.empty()) //***********//
                {
                    Cood now=Q.front();
                    Q.pop();
                    book[now.x][now.y]=false;
                    for (int i=0;i<=3;++i)
                    {
                        Cood tmp;
                        tmp.x=now.x+dx[i];
                        tmp.y=now.y+dy[i];
                        if (tmp.x<1 || tmp.x>n || tmp.y<1 || tmp.y>m) continue;
                        if (temp[tmp.x][tmp.y]>temp[now.x][now.y]+1)
                        {
                            temp[tmp.x][tmp.y]=temp[now.x][now.y]+1;
                            if (!book[tmp.x][tmp.y])
                            {
                                book[tmp.x][tmp.y]=true;
                                Q.push(tmp);
                            }
                        }
                    }
                }
    
                for (auto g:G[i])
                    dp[g.x][g.y]=temp[g.x][g.y];
            }
        }
    
        Cood &ans=G[p][0];
        printf("%d
    ",dp[ans.x][ans.y]);
    }
    
    /* http://codeforces.com/problemset/problem/677/D */
  • 相关阅读:
    #2019120500018-LG 小雨的数字游戏
    假期Noip笔记
    #2019120500016 逆序对与归并排序
    #2019120500015-LG 全排列
    #2019120500014-LG 采药
    #2019120500013-LG 合并果子
    二分与三分
    #2019120500012-LG 小鱼比可爱
    #2019120500011-LG 约瑟夫问题&玩具谜题
    HDU 5738 共线点集
  • 原文地址:https://www.cnblogs.com/123-123/p/5579283.html
Copyright © 2011-2022 走看看