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\n",dp[ans.x][ans.y]);
}

/* http://codeforces.com/problemset/problem/677/D */
时间: 2024-08-27 06:45:59

codeforce 677D Vanya and Treasure的相关文章

CodeForces 677D Vanya and Treasure

$dp$,树状数组. 很明显这是一个$DAG$上的$dp$,由于边太多,暴力$dp$会超时,需要优化. 例如计算$dp[x][y]$,可以将区域分成四块,$dp[x][y]$取四块中的最小值,每一块用一个二维树状数组维护最小值即可. 每次扩展一层需要一个新的树状数组,因为每次初始化树状数组会超时,所以可以额外开一个数组记录一下每一个点是第几次更新的. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<

Codeforces Round #355 (Div. 2) D. Vanya and Treasure 分治暴力

D. Vanya and Treasure Vanya is in the palace that can be represented as a grid n?×?m. Each room contains a single chest, an the room located in the i-th row and j-th columns contains the chest of type aij. Each chest of type x?≤?p?-?1 contains a key

CodeForce 677B Vanya and Food Processor

 Vanya and Food Processor Vanya smashes potato in a vertical food processor. At each moment of time the height of the potato in the processor doesn't exceed h and the processor smashes k centimeters of potato each second. If there are less than k cen

CodeForce 677C - Vanya and Label

Vanya and Label While walking down the street Vanya saw a label "Hide&Seek". Because he is a programmer, he used & as a bitwise AND for these two words represented as a integers in base 64 and got new word. Now Vanya thinks of some strin

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 &

CodeForce 677D Boulevard

Boulevard Welcoming autumn evening is the best for walking along the boulevard and n people decided to do so. The boulevard can be represented as the axis Ox. For every person there are three parameters characterizing the behavior: ti, si, fi — the m

CF #355div2 D 宝藏与钥匙 dp 二维数组智商题

D. Vanya and Treasure time limit per test 1.5 seconds memory limit per test 256 megabytes input standard input output standard output Vanya is in the palace that can be represented as a grid n × m. Each room contains a single chest, an the room locat

UVa 587 - There&#39;s treasure everywhere!

题目:你开始在坐标原点,想去目的地,给你一系列的指路信息,问目的地的位置和到原点的距离. 分析:模拟,计算几何.直接按照顺序计算即可,利用相对坐标求绝对坐标. 说明:注意输入格式. #include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> using namespac

Codeforces 552E Vanya and Brackets(贪心 + 表达式计算)

题目链接 Vanya and Brackets 题目大意是给出一个只由1-9的数.乘号和加号组成的表达式,若要在这个表达式中加上一对括号,求加上括号的表达式的最大值. 我们发现,左括号的位置肯定是最左端或者某个乘号右边,右括号的位置肯定是最右段或者某个乘号左边. 而乘号最多只有15个,那么暴力枚举就可以了. #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b);