链接

Codeforces 677D Vanya and Treasure

题意

n*m中有p个type,经过了任意一个 type=i 的各自才能打开 type=i+1 的钥匙,最初有type=1的钥匙, 问拿到type=p的钥匙最少需要走多少步

思路

第一想法就是按type来递推, 将type相同的存到一起,dp[i][j]=min(dp[i][j], dp[k][l]+distance([i][j], [k][l])),其中 a[i][j] = a[k][l]+1. 但这样type相同的个数较多时就超时了,所以根据type的个数,较多时使用BFS就可以了。 我没有仔细研究时间复杂度就过了,官方题解好像有均摊复杂度的证明。

代码

#include <iostream>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <string> #define LL long long
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MOD 1000000007
using namespace std; struct POS{
int x, y;
POS(int x = 0, int y = 0) :x(x), y(y){};
};
vector<POS> s[90005];
int a[305][305];
int d[305][305];
bool vis[305][305];
int dp[305][305];
const int step[4][2] = { 1, 0, 0, 1, -1, 0, 0, -1 };
int get_distance(POS &a, POS &b){
return abs(a.x - b.x) + abs(a.y - b.y);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int n, m, p;
while (~scanf("%d%d%d", &n, &m, &p)){
int x;
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= m; ++j){
scanf("%d", &a[i][j]);
s[a[i][j]].push_back(POS(i, j));
}
}
memset(dp, INF, sizeof(dp));
for (int i = 0; i < s[1].size(); ++i){
dp[s[1][i].x][s[1][i].y] = s[1][i].x + s[1][i].y - 2;
}
for (int i = 2; i <= p; ++i){
if (s[i].size() * s[i - 1].size() < n * m){
for (int j = 0; j < s[i].size(); ++j){
POS J = s[i][j];
for (int k = 0; k < s[i - 1].size(); ++k){
POS K = s[i - 1][k];
dp[J.x][J.y] = min(dp[K.x][K.y] + get_distance(J, K), dp[J.x][J.y]);
}
}
}
else{
memset(d, INF, sizeof(d));
memset(vis, 0, sizeof(vis));
queue<POS> Q;
for (int j = 0; j < s[i - 1].size(); ++j){
POS J = s[i - 1][j];
Q.push(J);
vis[J.x][J.y] = true;
d[J.x][J.y] = dp[J.x][J.y];
}
while (!Q.empty()){
POS u = Q.front();
Q.pop();
vis[u.x][u.y] = false;
for (int j = 0; j < 4; ++j){
int x = u.x + step[j][0];
int y = u.y + step[j][1];
if (a[u.x][u.y] == i) dp[u.x][u.y] = min(dp[u.x][u.y], d[u.x][u.y]);
if (x < 1 || x > n || y < 1 || y > m) continue;
if (d[x][y] > d[u.x][u.y] + 1){
d[x][y] = d[u.x][u.y] + 1;
if (!vis[x][y]){
vis[x][y] = true;
if (a[x][y] == i){
dp[x][y] = min(dp[x][y], d[x][y]);
}
Q.push(POS(x, y));
}
}
}
}
}
}
POS K = s[p][0];
cout << dp[K.x][K.y] << endl;
}
}

Codeforces 677D Vanya and Treasure 暴力+BFS的更多相关文章

  1. CodeForces 677D. Vanya and Treasure 枚举行列

    677D. Vanya and Treasure 题意: 给定一张n*m的图,图上每个点标有1~p的值,你初始在(1,1)点,你必须按照V:1,2,3...p的顺序走图上的点,问你如何走时间最少. 思 ...

  2. Codeforces 677D - Vanya and Treasure - [DP+优先队列BFS]

    题目链接:http://codeforces.com/problemset/problem/677/D 题意: 有 $n \times m$ 的网格,每个网格上有一个棋子,棋子种类为 $t[i][j] ...

  3. CodeForces 677D Vanya and Treasure

    $dp$,树状数组. 很明显这是一个$DAG$上的$dp$,由于边太多,暴力$dp$会超时,需要优化. 例如计算$dp[x][y]$,可以将区域分成四块,$dp[x][y]$取四块中的最小值,每一块用 ...

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

    D. Vanya and Treasure 题目连接: http://www.codeforces.com/contest/677/problem/D Description Vanya is in ...

  5. codeforces 677D D. Vanya and Treasure(二维线段树)

    题目链接: D. Vanya and Treasure time limit per test 1.5 seconds memory limit per test 256 megabytes inpu ...

  6. 题解-CF677D Vanya and Treasure

    CF677D Vanya and Treasure 有一个 \(n\times m\) 的矩阵 \(a(1\le a_{i,j}\le p)\),求从起点 \((1,1)\) 出发依次遍历值为 \(1 ...

  7. hdu 1195:Open the Lock(暴力BFS广搜)

    Open the Lock Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  8. codeforces 492E. Vanya and Field(exgcd求逆元)

    题目链接:codeforces 492e vanya and field 留个扩展gcd求逆元的板子. 设i,j为每颗苹果树的位置,因为gcd(n,dx) = 1,gcd(n,dy) = 1,所以当走 ...

  9. codeforces 677D(分层图dp)

    Codeforces 677D 传送门:https://codeforces.com/contest/677/problem/D 题意: 给你一个n*m的方格图,每个点有一个权值val,现在要求你从坐 ...

随机推荐

  1. php如何判断两个时间戳是一天

    $date1 = getdate(strtotime('2013-12-31')); $date11 = getdate(strtotime('2014-01-01')); $date2 = getd ...

  2. jqueryui slider

    <!doctype html><html lang="en"><head> <meta charset="utf-8" ...

  3. Python multiprocessing.Manager介绍和实例(进程间共享数据)

    Python中进程间共享数据,处理基本的queue,pipe和value+array外,还提供了更高层次的封装.使用multiprocessing.Manager可以简单地使用这些高级接口. Mana ...

  4. 淘宝druid报错:javax.management.InstanceNotFoundException: com.alibaba.druid:type=DruidDataSourceStat

    问题: 启动tomcat报错: Tomat报出一下异常:ERROR [com.alibaba.druid.stat.DruidDataSourceStatManager] – unregister m ...

  5. 理解HashMap底层原理,一个简单的HashMap例子

    package com.jl.testmap; /** * 自定义一个HashMap * @author JiangLai * */ public class MyHashMap<K,V> ...

  6. vue-cli 3.0 安装和创建项目流程

    使用前我们先了解下3.0较2.0有哪些区别 一.3.0 新加入了 TypeScript 以及 PWA 的支持二.部分命令发生了变化: 1.下载安装  npm install -g vue@cli 2. ...

  7. (转载) listview实现微信朋友圈嵌套

    listview实现微信朋友圈嵌套 标签: androidlistview 2016-01-06 00:05 572人阅读 评论(0) 收藏 举报  分类: android(8)  版权声明:本文为博 ...

  8. poj 2135 Farm Tour【 最小费用最大流 】

    第一道费用流的题目--- 其实---还是不是很懂,只知道沿着最短路找增广路 建图 源点到1连一条容量为2(因为要来回),费用为0的边 n到汇点连一条容量为2,费用为0的边 另外的就是题目中输入的了 另 ...

  9. hdu 3549 Flow Problem 【最大流】

    其实还是不是很懂dinic----- 抄了一个模板--- http://www.cnblogs.com/naturepengchen/articles/4403408.html 先放在这里--- #i ...

  10. jsp错误页面的处理

    局部的错误处理 1,errorpage 在错误页面指令page中声明errorpage="要显示的页面地址" 在要显示的页面page中声明iserrorpage="tru ...