链接

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. 编译最新版webrtc源码和编译好的整个项目10多个G【分享】

    编译最新版webrtc源码和编译好的整个项目10多个G[分享] 参考https://webrtc.org/native-code/development/编译最新版webrtc源码: Git clon ...

  2. HTML5学习笔记(四):关于表格

    在一个实例中碰到表格,总结下,先上代码,例: <table border="1"> <thead> <th>表头</th> < ...

  3. webstorm配置Monokai-Sublime.jar主题

    https://github.com/OtaK/jetbrains-monokai-sublime 导入下载的Monokai-Sublime.jar jar包即可使用.

  4. ROS集成开发环境RoboWare Studio安装教程

    前言:很多人说vim是最快的,所以我选择用roboware. ROS 自带的编辑器vim增加插件,效果如下: RoboWare Studio,效果如下: 下面开始安装. 一.安装 去官网 http:/ ...

  5. 初探MVC路由

    文章目录: 1.认识理解URL,以及简单的路由 2.特性路由.传统路由.区域路由 3.路由生成URL&&绑定到操作&&路由约束 1.认识理解URL,以及简单的路由  默 ...

  6. 手机、电脑、安卓、iOS、微信浏览器判断

    微信浏览器判断: // true为微信浏览器function is_weixin() { var ua = window.navigator.userAgent.toLowerCase(); if ( ...

  7. c#中 abstract 和 virtual 的区别与用法

    先来看abstract方法,顾名思义,abstract方法就是抽象方法. 1.抽象方法就是没有实现的,必须是形如:  public abstract void Init();   2.拥有抽象方法的类 ...

  8. 杭电 1114 Piggy-Bank【完全背包】

    解题思路,首先很容易想到方程f[v]=min(f[v],f[v-w[i]+p[i]),因为是要求当包装满的时候(因为题目中给出的是包的质量是一定的),包里面装的钱最少,所以将f[]初始化成一个很大的数 ...

  9. jsp+jdbc实现用户登录

    1.1 创建数据库表 表名:user 字段: userid   保存用户的登录id name     用户名 password 密码 1.2 实现思路 a. 用户登录,则需要有个一个表单页,此页面可输 ...

  10. Java web课程学习之Request和Response

    request和response l HttpServletRequest l 请求转发 l HttpServletResponse l 请求重定向   请求流程 每次请求service(),都会由容 ...