题目描述

Michael喜欢滑雪。这并不奇怪,因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道在一个区域中最长的滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子:

1   2   3   4   5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可行的滑坡为24-17-16-124-17-16-124-17-16-1(从242424开始,在111结束)。当然25-24-23-...-3-2-125-24-23-...-3-2-125-24-23-...-3-2-1更长。事实上,这是最长的一条。

输入输出格式

输入格式:

输入的第一行为表示区域的二维数组的行数RRR和列数CCC(1≤R1≤R1≤R,C≤100C≤100C≤100)。下面是RRR行,每行有CCC个数,代表高度(两个数字之间用1个空格间隔)。

输出格式:

输出区域中最长滑坡的长度。

输入输出样例

输入样例#1:

5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

输出样例#1:

25

思路

可以轻易地推出状态转移方程为:

dp[i][j]=max(dp[i−1][j]+1,dp[i][j]  (if dp[i][j]>dp[i−1][j])
dp[i][j]=max(dp[i-1][j]+1,dp[i][j]\ \ (if\ dp[i][j]>dp[i-1][j])
dp[i][j]=max(dp[i−1][j]+1,dp[i][j]  (if dp[i][j]>dp[i−1][j])

dp[i][j]=max(dp[i+1][j]+1,dp[i][j]  (if dp[i][j]>dp[i+1][j])
dp[i][j]=max(dp[i+1][j]+1,dp[i][j]\ \ (if\ dp[i][j]>dp[i+1][j])
dp[i][j]=max(dp[i+1][j]+1,dp[i][j]  (if dp[i][j]>dp[i+1][j])

dp[i][j]=max(dp[i][j−1]+1,dp[i][j]  (if dp[i][j]>dp[i][j−1])
dp[i][j]=max(dp[i][j-1]+1,dp[i][j]\ \ (if\ dp[i][j]>dp[i][j-1])
dp[i][j]=max(dp[i][j−1]+1,dp[i][j]  (if dp[i][j]>dp[i][j−1])

dp[i][j]=max(dp[i][j+1]+1,dp[i][j]  (if dp[i][j]>dp[i][j+1])
dp[i][j]=max(dp[i][j+1]+1,dp[i][j]\ \ (if\ dp[i][j]>dp[i][j+1])
dp[i][j]=max(dp[i][j+1]+1,dp[i][j]  (if dp[i][j]>dp[i][j+1])

但是dp[i−1][j],dp[i+1][j],dp[i][j−1],dp[i][j+1]dp[i-1][j],dp[i+1][j],dp[i][j-1],dp[i][j+1]dp[i−1][j],dp[i+1][j],dp[i][j−1],dp[i][j+1]的值不能通过普通的线性dp来求的,所以需要进行记忆化搜索来遍历所有的状态,并进行记忆化,这样就可以获得上述四个状态的值了,然后进行dp即可

也可以将二维的地图进行降维,然后进行线性dp,具体方法请看dalao博客:https://sparky.blog.luogu.org/solution-p1434

AC代码

/*************************************************************************

	 > Author: WZY
> School: HPU
> Created Time: 2019-02-06 20:45:27 ************************************************************************/
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ms(a,b) memset(a,b,sizeof(a))
#define INF 0x7f7f7f7f
const int maxn=1e3+10;
const int mod=1e9+7;
using namespace std;
int a[maxn][maxn];
int dp[maxn][maxn];
int dir[4][2]={1,0,-1,0,0,1,0,-1};
int n,m;
int dfs(int x,int y)
{
if(dp[x][y])
return dp[x][y];
int _=0;
for(int i=0;i<4;i++)
{
int dx=x+dir[i][0];
int dy=y+dir[i][1];
if(dx<=n&&dx>0&&dy<=m&&dy>0&&a[x][y]>a[dx][dy])
_=max(dfs(dx,dy)+1,_);
}
dp[x][y]=max(_,dp[x][y]);
return dp[x][y];
}
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
ms(dp,0);
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
ans=max(ans,dfs(i,j));
cout<<ans+1<<endl;
return 0;
}

洛谷 P1434 [SHOI2002]滑雪(DP,记忆化搜索)的更多相关文章

  1. 【洛谷1434 [SHOI2002]滑雪】记忆化搜索

    AC代码 #include <bits/stdc++.h> using namespace std; #define ms(a,b) memset(a,b,sizeof(a)) typed ...

  2. 洛谷-P1434 [SHOI2002]滑雪 (记忆化搜索)

    题意:有一个\(R*C\)的矩阵,可以从矩阵中的任意一个数开始,每次都可以向上下左右选一个比当前位置小的数走,求走到\(1\)的最长路径长度. 题解:这题很明显看到就知道是dfs,但是直接爆搜会TLE ...

  3. 洛谷P1434 [SHOI2002]滑雪

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

  4. 洛谷3953 (NOIp2017) 逛公园——记忆化搜索+用栈判0环

    题目:https://www.luogu.org/problemnew/show/P3953 因为K只有50,所以想到用dp[ cr ][ j ]表示在点cr.比最短路多走了 j 的方案数.(看了TJ ...

  5. 洛谷P1192 台阶问题【记忆化搜索】

    题目:https://www.luogu.org/problemnew/show/P1192 题意: 给定n和k,一个人一次可以迈1~k步,问走n步有多少种方案. 思路: 本来傻乎乎上来就递归,显然会 ...

  6. 洛谷P1040 加分二叉树【记忆化搜索】

    题目链接:https://www.luogu.org/problemnew/show/P1040 题意: 某一个二叉树的中序遍历是1~n,每个节点有一个分数(正整数). 二叉树的分数是左子树分数乘右子 ...

  7. 洛谷 P1434 [SHOI2002]滑雪

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

  8. 洛谷 P1434 [SHOI2002]滑雪 解题报告

    这题方法有很多, 这里介绍2种: 方法1 很容易想到搜索, bfs或dfs应该都可以, 就不放代码了: 方法2 这题还可以用 dp 来做. 做法:先将每个点按照高度从小到大排序,因为大的点只能向小的点 ...

  9. 洛谷P3906 Hoof Paper, Scissor (记忆化搜索)

    这道题问的是石头剪刀布的的出题问题 首先不难看出这是个dp题 其次这道题的状态也很好确定,之前输赢与之后无关,确定三个状态:当前位置,当前手势,当前剩余次数,所以对于剪刀,要么出石头+1分用一次机会, ...

随机推荐

  1. [云原生]Docker - 安装&卸载

    目录 系统要求 卸载旧版本 安装Docker 方法一:通过repo安装 设置Repository 安装Docker Engine 升级Docker Engine 方法二:通过package安装 方法三 ...

  2. adhere, adjust, adjacent

    adhere to stick,不是to here. 在古英语里,stick是twig(细树枝).fasten(想必是用twig来固定).后引申为粘住.stick还有stab, pierce的意思,想 ...

  3. android获取路径目录方法

    Environment常用方法: getExternalStrongeDirectory() 返回File,获取外部存储目录即SDCard getDownloadCacheDirectory() 返回 ...

  4. 线程开启的第一种方法:通过创建Thread的子类的对象的方式

    package cn.itcast.demo16.demo06.Thread;/** * @author newcityman * @date 2019/7/22 - 21:47 */public c ...

  5. 初步接触Linux命令

    目录 虚拟机快照 1.首先将已经运行的系统关机 2.找到快照 拍摄快照 3.找到克隆 下一步 有几个快照会显示几个 4.克隆完成后 要修改一下IP 不然无法同时运行两个虚拟机系统 系统介绍 1.pin ...

  6. 莫烦python教程学习笔记——利用交叉验证计算模型得分、选择模型参数

    # View more python learning tutorial on my Youtube and Youku channel!!! # Youtube video tutorial: ht ...

  7. [IDEA] chapter_reader - idea看小说插件 idea阅读插件 idea摸鱼插件

    目录 1. 简述: 2. 使用说明: 2.1 版本说明: 2.2 重要说明: 2.3 简单使用方法: 2.4 目前支持的网站有 (新↓): 2.5 菜单介绍: 2.6 快捷键设置及推荐: 2.7 在线 ...

  8. [BUUCTF]PWN5——ciscn_2019_n_1

    [BUUCTF]PWN5--ciscn_2019_n_1 题目网址:https://buuoj.cn/challenges#ciscn_2019_n_1 步骤: 例行检查,64位,开启了nx保护 nc ...

  9. [BUUCTF]REVERSE——reverse2

    reverse2 附件 例行检查,64位目标 64位ida载入,首先shift+f12检索程序里的字符串 得到了"this is the right flag!" 的提示字符串,还 ...

  10. Table.ReverseRows反转…Reverse…(Power Query 之 M 语言)

    数据源: 任意五行两列 目标: 将原排列顺序颠倒 操作过程: [转换]>[反转行] M公式:  = Table.ReverseRows( 表 ) 扩展: 反转列表:= List.Reverse( ...