CF #355div2 D 宝藏与钥匙 dp 二维数组智商题
1.5 seconds
256 megabytes
standard input
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 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 that can open any chest of type x + 1, and all chests of type 1 are not locked. There is exactly one chest of type p and it contains a treasure.
Vanya starts in cell (1, 1) (top left corner). What is the minimum total distance Vanya has to walk in order to get the treasure? Consider the distance between cell (r1, c1) (the cell in the row r1 and column c1) and (r2, c2) is equal to |r1 - r2| + |c1 - c2|.
The first line of the input contains three integers n, m and p (1 ≤ n, m ≤ 300, 1 ≤ p ≤ n·m) — the number of rows and columns in the table representing the palace and the number of different types of the chests, respectively.
Each of the following n lines contains m integers aij (1 ≤ aij ≤ p) — the types of the chests in corresponding rooms. It's guaranteed that for each x from 1 to p there is at least one chest of this type (that is, there exists a pair of r and c, such that arc = x). Also, it's guaranteed that there is exactly one chest of type p.
Print one integer — the minimum possible total distance Vanya has to walk in order to get the treasure from the chest of type p.
3 4 3
2 1 1 1
1 1 1 1
2 1 1 3
5
3 3 9
1 3 5
8 9 7
4 6 2
22
3 4 12
1 2 3 4
8 7 6 5
9 10 11 12
最终权值为p的格子中(只有一个),只要曾经经过权值为i的格子就能打开权值为i+1的格子中的宝藏,现在要打开权值为p的格子中的宝藏问需要经过的最少步数。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define MM(a,b) memset(a,b,sizeof(a));
const double eps = 1e-10;
const int inf =0x7f7f7f7f;
const double pi=acos(-1);
const int maxn=5+100000;
const int mod=1e9+7; int dis[305][305],vis[305][305],ans[305][305];
struct node{
int x,y;
}ne[maxn];
vector<node> G[maxn]; ll gdis(node u,node v)
{
return abs(u.x-v.x)+abs(u.y-v.y);
} int main()
{
int n,m,p,v,ex,ey;
while(~scanf("%d %d %d",&n,&m,&p))
{
int cnt=0,k1,k2;
MM(vis,-1);MM(dis,inf);MM(ans,inf);
for(int i=1;i<=p;i++) G[i].clear();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&v);
G[v].push_back((node){i,j});
if(v==p) {ex=i;ey=j;}
}
for(int i=1;i<=m;i++)
{
dis[1][i]=i-1;
vis[1][i]=0;
}
for(int u=1;u<=p;u++)
{
for(int k=0;k<G[u].size();k++)
{
int r=G[u][k].x,l=G[u][k].y;
for(int i=1;i<=n;i++)
if(vis[i][l]==u-1)
ans[r][l]=min(ans[r][l],dis[i][l]+abs(i-r));
}
for(int k=0;k<G[u].size();k++)
{
int r=G[u][k].x,l=G[u][k].y;
for(int j=1;j<=m;j++)
if(vis[r][j]!=u)
{
vis[r][j]=u;
dis[r][j]=ans[r][l]+abs(l-j);
}
else
dis[r][j]=min(dis[r][j],ans[r][l]+abs(l-j));
}
}
printf("%d\n",ans[ex][ey]);
}
return 0;
}
分析:设置dis和vis以及ans三个数组,假设[i][j]格子中的权值为v,ans[i][j]代表,从最左上角格子开始走,且经过了1-v的格子后到达该格子的最少步数(最终答案就是ans[ex][ey])dis[i][j]代表
在经过了1-vis[i][j]的权值后,到达该格子的最少步数,vis[i][j]代表该格子所在的行所更新的最大的权值
CF #355div2 D 宝藏与钥匙 dp 二维数组智商题的更多相关文章
- 剑指 offer set 1 二维数组中查找
总结 1. 二维数组搜索题遇到两个了, 一个是 Leetcode 上 search in 2D matrix. 那道题比较简单, 因为下一行的所有元素大于上一行的. 这道题对二维矩阵的要求比较松, 起 ...
- 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP
题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...
- dp --- 二维dp + 最大上升子序列
<传送门> 滑雪 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 74477 Accepted: 27574 ...
- 问题 A: 【动态规划】采药_二维数组_一维数组
问题 A: [动态规划]采药 时间限制: 1 Sec 内存限制: 64 MB提交: 35 解决: 15[提交][状态][讨论版] 题目描述 山洞里有一些不同的草药,采每一株都需要一些时间,每一株也 ...
- C++二维数组动态内存分配
对于二维数组和二维指针的内存的分配 这里首选说一下一维指针和一维数组的内存分配情况. 一维: 数组:形如int a[5];这里定义了一个一维数组a,并且数组的元素个数是5,这里的a是这五个元素的整体 ...
- (二维数组 亿进制 或 滚动数组) Hat's Fibonacci hdu1250
Hat's Fibonacci Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- C语言复习---二维数组和二级指针的关系:没关系,别瞎想(重点)
前提:一维数组和一维指针为什么可以替换使用? ] = { , , }; int *p = a; ; i < ; i++) printf("%d ", *(p + i)); 上 ...
- Poj1050_To the Max(二维数组最大字段和)
一.Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is an ...
- C++中vecotr表示二维数组并自己实现一个Grid类
1 C++中使用vector来表示二维数组 声明一个二维数组: vector<vector<int>> dp(row, vector<int>(col)); 将变量 ...
随机推荐
- [转帖]通俗易懂的Docker 入门教程
看完此文,妈妈还会担心你docker入不了门? http://www.17coding.info/article/24 上周对象突然心血来潮说想养个小宠物,我问想养啥她又说随便,你看着办!!!这我 ...
- round函数——银行家舍入算法
在处理四舍五入时,相信大部分人会使用math.round函数(不同的语言应该都有).有没有考虑过,这个函数是不是自己所需要的? po主碰到的问题是用来计算平均分.有个顶真的学生反映,明明是86.5,怎 ...
- Centos7 更换为网易YUM源
当我们刚刚安装系统的时候 yum 的速度那是真滴慢所以我们就需要一个更加快速的镜像,这时候网易镜像带给我们便捷.下面来一起更换吧! 备份当前的 yum 源 # yum 源在目录 /etc/yum.re ...
- JavaSSM框架精选50道面试题
JavaSSM框架精选50道面试题 2019年02月13日 19:04:43 EerhtSedah 阅读数 7760更多 分类专栏: 面试题 版权声明:本文为博主原创文章,遵循CC 4.0 BY- ...
- 最新省市区地区数据sql版本(2019年1月)
版本 统计标准2017版 来源 http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/ 建表 CREATE TABLE `area` ( `id` varc ...
- postgres 常规操作杂记
分布式:1.扩容不方便(数据重分布)2.分布键变更很麻烦3.分布键选择(架构设计)谨慎4.跨库join性能差5.分布式事务性能差6.sql限制多,功能确实多7.应用改造成本巨大8.全局一致性时间点恢复 ...
- Linux小知识:sudo su和su的区别
Linux小知识:sudo su和su的区别 本文是学习笔记,视频地址:https://www.bilibili.com/video/av62836363 su是申请切换root用户,需要申请root ...
- MySql查询进阶
1.1 as关键字 用于 给显示结果中字段 或者 表 起别名 select 别名.字段名 from 表名 as 别名 where 条件语句 # 对字段起别名 select id as '编号', na ...
- ubuntu18.04系统安装及php7.2,apache2,mysql8,git,svn,composer,vs code 到安装 php 扩展配置php.ini 实现 laravel5.8 运行
简介:记录自己从系统安装到环境配置完毕运行laravel的记录 • 下载ubuntu18.04桌面版 ○ ubuntu18.04中国官网 https://cn.ubuntu.com ...
- MySQL中自定义排序
在开发时候,我们经常使用的是默认的排序规则,但在某些特殊情况下,通过指定顺序来进行排序 -- fileld自定义排序时,应该是非主键的,否则主键是无效 SELECT * FROM customer W ...