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)); 将变量 ...
随机推荐
- 5表联查yii框架权限控制
一:控制器部分 <?php namespace app\controllers; use yii\web\Controller; class PreController extends Cont ...
- Linux-1.3目录结构,基础命令
1.Linux目录结构 2.Linux基础命令(常用) ctrl+alt+T(打开终端) cd 切换文件夹(pwd查看当前目录) cd /home 绝对路径 以根目录开头 cd admin 相对路径 ...
- Dubbo消费方服务调用过程源码分析
参考:dubbo消费方服务调用过程源码分析dubbo基于spring的构建分析Dubbo概述--调用过程dubbo 请求调用过程分析dubbo集群容错机制代码分析1dubbo集群容错策略的代码分析2d ...
- 自定义ResultMap查询,这里的关联写法只能用于不分页
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "- ...
- O020、理解 Glance
参考https://www.cnblogs.com/CloudMan6/p/5384923.html OpenStack 由 Glance 提供 Image 服务. 理解 Glance ...
- html/css弹性布局的几大常用属性详解
弹性布局的名称概念: 1.容器:需要添加弹性布局的父元素:项目:弹性布局容器中的每一个子元素,称为项目. 2.主轴:在弹性布局中,我们会通过属性规定水平/垂直方向(flex-direction)为主轴 ...
- css3实现div自动左右动
<!DOCTYPE html> <meta charset="UTF-8"/> <html> <head> <style> ...
- CSS-百分百布局
1.照片随着大小变化: 这里面重点就是每个包裹盒子是25%,图片是100%显示: <div class="box2"> <p> //这里都是4个: < ...
- 标准模板库(STL)
组件: 容器:管理某类对象的集合. 迭代器:用来在一个对象集合内遍历元素. 算法:处理集合内的元素. 容器 序列式容器:顾名思义.array,vector,deque,list 和 forward_l ...
- emwin之窗口ID的唯一性
@2019-04-30 [小记] emwin窗口ID是唯一的 emwin多次创建同一窗口,则窗口句柄不同,多次删除窗口采取LIFO机制,即最新创建的窗口被首先删除 获取多次创建同一窗口的ID,准确位置 ...