题源:【戳这里】

洛谷博客链接:【戳这里】


我觉得这道题主要方法应该有两种:

下面会分别对这两种方法进行简述


一,动态规划法
首先的想法是用L(i,j)表示从点(i,j)出发能到达的最长距离。因为从(i,j)出发最少能滑行自己1格,所以每个点L值都先初始化为1

我们可以从 (i,j) 出发,向四周寻找,如果四周没有比他低的点,那么L(i,j)即为1,否则L(i,j)就为从(i,j)出发四周高度比L低且L值最大的那个点P的L值加1
递推时的顺序为点的高度由低到高,那么在递推过程中,计算L(i,j)时,他四周比他低的点P的L值一定已经被计算出来了
接下来需要解决的问题便是如何按点的高度由小到大递推

关于这个问题,我们难道要每次递推时用两遍循环找出当前未递推的最低点?

显然不可取,时间复杂度会爆炸的。那么就考虑能否一个sort()解决问题(懒得自己写排序)。sort()能给一个二维数组排序?不知大佬们怎么想,反正本蒟蒻不会。。。那为了`sort()更香可以方便的使用,我用一个一维数组进行存储每个点的数据。

这时候不得不说,结构体真香真的实用。下面用代码直观地说一下这个结构体

 struct Point{
int r; //行号
int c; //列号
int h; //高度
bool operator < (const Point & p) const {
return h < p.h;
}//构造函数,不懂的同学可以写一个cmp代替,下面代码会有特别说明
};Point point[];

为了方便储存以及不造成浪费(个人习惯)这里i和j都从0开始取,那么点(i,j)用point数组存的下标为c * i + j
 由于i,j从0开始存,c * i + j这个式子表示的是第i+1行第j+1个数,那么,i最大为R-1,j最大为C-1,整个数组最大下标为C*(R-1)+C-1,即C*R-1
 若i,j从1开始取,为保证运算方便及善待空间,下标应为C*(i-1)+j-1

该算法的分析已给出,大家可以结合代码自行理解

 #include <iostream>//头文件,不多解释
#include <cstdio>
#include <algorithm>
using namespace std;
struct Point{
int r;//行号
int c;//列号
int h;//高度
bool operator < (const Point & p) const {
return h < p.h;//构造函数,不会的可删掉看下面cmp
}
};Point point[];
int cmp(Point a,Point b){
if (a.h < b.h) //如果a的高度小于b的高度
return ;//返回真
else
return ;//否则返回假
}
int R,C,ans = -0x3ffff;//需初始化ans为较小值(害怕玄学出错)
int a[][],d[][];//a为每点的高度,d为该点可滑行的最大值
int main(){
cin >> R >> C;
for (int i = ;i < R;i ++)
for (int j = ;j < C;j ++){
cin >> a[i][j];//输入点的高度
point[i * C + j].h = a[i][j];//根据上面所说的下标,
point[i * C + j].r = i; //对点的数据进行存储
point[i * C + j].c = j;
d[i][j] = ; //初始可滑行长度为1
}
sort(point,point + R * C);//如果用了cmp可换为sort(point,point + R * C,cmp);
for (int i = ;i < R * C;i ++){
int r = point[i].r;//找一个替身,怕玄学或运算时出错
int c = point[i].c;//同理
if (r > && a[r - ][c] < a[r][c])//找上面的
d[r][c] = max(d[r][c],d[r - ][c] + );//进行更新
if (c > && a[r][c - ] < a[r][c])//找左面的
d[r][c] = max(d[r][c],d[r][c - ] + );//进行更新
if (r < R - && a[r + ][c] < a[r][c])//找下面的
d[r][c] = max(d[r][c],d[r + ][c] + );//进行更新
if (c < C - && a[r][c + ] < a[r][c])//找右面的
d[r][c] = max(d[r][c],d[r][c + ] + ); //进行更新
}
for (int i = ;i < R;i ++)
for (int j = ;j < C;j ++)
ans = max(ans,d[i][j]); //找出最大值
cout << ans;
return ;//完美撒花

c++ Code


 二、搜索

相信大家都会想到DFS,但若是单纯的DFS,会TLE一个点,所以,我们就要考虑到记忆化搜索。那么也很好实现,具体请见下方代码:

 #include <iostream>
#include <cstdio>
using namespace std;
int R,C;
int g1[] = {,,,-};//定义寻找的4个方向
int g2[] = {-,,,};
int m[][];//储存每个点的高度
int lj[][];//储存每个点可滑行的最大长度
int maxn,lr;
int dfs(int i,int j){
if (lj[i][j] - )//判断是否搜过,因为下面将每一个点的最初滑行长度为1
//如果该点最长长度-1为0,说明该点未被搜过
return lj[i][j];
for (int o = ;o < ;o ++)//向4个方向搜
if (i + g1[o] >= && i + g1[o] < R && j + g2[o] >= && j + g2[o] < C && m[i + g1[o]][j + g2[o]] < m[i][j]){//保证不越界
lj[i][j] = max(lj[i][j],dfs(i + g1[o],j + g2[o]) + );//进行搜索及更新
}
return lj[i][j];
}
int main(){
cin >> R >> C;
for (int i = ;i < R;i ++)//初始化
for (int j = ;j < C;j ++)
lj[i][j] = ;
for (int i = ;i < R;i ++)
for (int j = ;j < C;j ++)
cin >> m[i][j];
for (int i = ;i < R;i ++)
for (int j = ;j < C;j ++){
if (lj[i][j] - != ){//如果该点被搜过
maxn = max(maxn,lj[i][j]);//直接更新
continue;
}
lj[i][j] = dfs(i,j);
maxn = max(maxn,lj[i][j]);
}
cout << maxn;
return ;//撒花
}

这就是该题本人的思路,希望能给你带来帮助

初步发布时间:2019.11.25持续修改完善

洛谷P1434滑雪讲解的更多相关文章

  1. 洛谷P1434滑雪题解及记忆化搜索的基本步骤

    题目 滑雪是一道dp及记忆化搜索的经典题目. 所谓记忆化搜索便是在搜索的过程中边记录边搜索的一个算法. 当下次搜到这里时,便直接使用. 而且记忆化搜索一定要满足无后效性,为什么呢,因为如果不满足无后效 ...

  2. 洛谷 p1434 滑雪【记忆化搜索】

    <题目链接> Michael喜欢滑雪.这并不奇怪,因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...

  3. 洛谷P1434 滑雪【记忆化搜索】

    题目:https://www.luogu.org/problemnew/show/P1434 题意: 给一个矩阵,矩阵中的数字代表海拔高度. 现在要找一条最长路径,使得路径上的海拔是递减的. 思路: ...

  4. 洛谷P1434 滑雪

    题目描述 Michael喜欢滑雪.这并不奇怪,因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道在一个区域中最长 ...

  5. 洛谷 - P1434 - 滑雪 - 有向图最长链

    https://www.luogu.org/problemnew/show/P1434 有向图的最长链怎么求?有环肯定不行,这里保证无环.(否则应该使用toposort先求出所有不带环的位置) 设dp ...

  6. 洛谷 P1434 滑雪

    题目描述 Michael喜欢滑雪.这并不奇怪,因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道在一个区域中最长 ...

  7. 洛谷—— P1434 滑雪

    https://www.luogu.org/problem/show?pid=1434#sub 题目描述 Michael喜欢滑雪.这并不奇怪,因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜 ...

  8. [洛谷P1434] [SHOI2007]滑雪

    题目链接: here we go 题外话: 谁能想到这是一道咕了两年的\(AC\)呢--当年是在搜索还半懂不懂的时候遇到的这道题,感觉真是难得要命()所以一直拖着不做,后面就下意识地逃避了搜索相关的内 ...

  9. 洛谷 P1434 [SHOI2002]滑雪

    这道题适合记忆化练手 毕竟总有些大佬虐题. 这个题有几个剪枝 1.记忆化 这个不用多说了吧 剪枝就是 如果 当前点到下面一个点的目前下降的高度+1 小于 下面那个点 能下降的高度 那么反过来,这个点不 ...

随机推荐

  1. cf1173 D. Nauuo and Circle

    链接 [cf]http://codeforces.com/contest/1175/problem/F) 思路 当1在1的位置做dp[i]为i的子树所有的方案. 一条性质是i的子树所占圆上的位置一定一 ...

  2. 【jmeter】Include Controller控件&Test Fragment的使用

    概念:简单说下Include Controller引用Test Fragment片段 Include Controller控件——给当前jmeter脚本引入外部片段的jmeter脚本(Test Fra ...

  3. jmeter(四十五)常用Beanshell脚本

    整理了一批jmeter常用的beanshell脚本供大家参考! 时间戳 import java.text.SimpleDateFormat; import java.util.Calendar; im ...

  4. jvm(三)指令重排 & 内存屏障 & 可见性 & volatile & happen before

    参考文档: https://tech.meituan.com/java-memory-reordering.html http://0xffffff.org/2017/02/21/40-atomic- ...

  5. 【转】vim复制与粘贴

    用vim写代码时,经常遇到这样的场景,复制多行,然后粘贴. 这样做:1. 将光标移动到要复制的文本开始的地方,按v进入可视模式.2. 将光标移动到要复制的文本的结束的地方,按y复制.此时vim会自动将 ...

  6. 阿里云ECS服务器相关配置以及操作---上(初学者)

    最近买了一台阿里云的ECS服务器 linux系统 centos镜像,把我相关的一些操作记录下来,供大家参考,不足之处欢迎指正. 首先买的过程就不用介绍了,根据自己的实际需要选择自己想要的配置,点击付钱 ...

  7. Shared variable in python's multiprocessing

    Shared variable in python's multiprocessing https://www.programcreek.com/python/example/58176/multip ...

  8. ROC曲线 VS PR曲线

    python机器学习-乳腺癌细胞挖掘(博主亲自录制视频)https://study.163.com/course/introduction.htm?courseId=1005269003&ut ...

  9. 编写基于TCP的应用程序

    编写基于TCP的应用程序   这似乎是一个非常简单的话题, 就跟"是个人就能做网站"一样, 你可能也认为"是个人就能写使用TCP socket的网络程序". 不 ...

  10. kubernetes篇 容器用户权限控制

    问题起源 问题起源于一个开发BUG:正常运行一段时间的POD,突然有一天运行报错了,错误是没有操作目录的权限,查其原因,原来是镜像被更新了,镜像添加了操作用户,而被操作的目录(NFS目录)并不具备普通 ...