本文为原创,转载请注明:http://www.cnblogs.com/kylewilson/

题目出处:

http://poj.org/problem?id=1088

题目描述:

区域由一个二维数组给出。数组的每个数字代表点的高度。如下:

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-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。

输入:

输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。

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

思路分析:

首先考考虑最终的目标状态,即已经找到了一条最大长度的滑坡,如下图:

绿色为起点,红色为终点;

可滑行的条件是高度递减,即原问题变为:在一个图中,找出从一个点到另一个占依次递减的最长路径。

貌似是一个搜索问题,用BFS或者DFS很容易搞定,即从一个点向4个方向搜索,直到无路可走,找出最长的路径。

这样需要枚举每一个点作为起点,发现之前很多的点已经搜索过了,还会继续搜索,重复计算,浪费时间。

所以此时要利用动态规划的思想,计算子问题结果,避免重复计算。

DFS+DP,也就是记忆化搜索,如果某一个点已经搜索过了,直接返回结果而不需要再搜索。

用f[i][j]表示以(i, j)为终点最长的滑坡长度

则状态转移如下:

f[i][j]=max(dfs(x,y)+1),其中(x,y)为(i,j)的4个方向上的点,并且高度递减

提示:

处理方向时可以提前定义一个常量2维数组,即方向向量,枚举时加上向量即可

C++源码如下:

github: https://github.com/Kyle-Wilson1/Poj/tree/master/P1088

#include <iostream>
#include <fstream>
#include <vector> using namespace std; const int direction[4][2] = {{0, -1},
{0, 1},
{1, 0},
{-1, 0}}; int maxOfTwo(int a, int b) {
return a > b ? a : b;
} int solve(vector<vector<int>> &snowMountain, vector<vector<int>> &f, int i, int j, int r, int c) {
int x, y;
if (f[i][j] != -1)
return f[i][j]; f[i][j] = 1;
for (int k = 0; k < 4; k++) {
x = i + direction[k][0];
y = j + direction[k][1]; //valid direction
if (x >= 0 && x < r && y >= 0 && y < c && snowMountain[i][j] > snowMountain[x][y]) {
f[i][j] = maxOfTwo(f[i][j], solve(snowMountain, f, x, y, r, c) + 1);
}
}
return f[i][j];
} int main() { ifstream fin("a.in");
ofstream fout("a.out"); int i, j, r, c, maxHeight = 0; fin >> r >> c; vector<vector<int>> snowMountain(r, vector<int>(c, 0));
vector<vector<int>> f(r, vector<int>(c, -1)); for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
fin >> snowMountain[i][j]; for (i = 0; i < r; i++)
for (j = 0; j < c; j++) {
maxHeight = maxOfTwo(maxHeight, solve(snowMountain, f, i, j, r, c));
} fout << maxHeight << endl; fin.close();
fout.close();
return 0;
}

Poj-P1088题解【动态规划/记忆化搜索】的更多相关文章

  1. sicily 1176. Two Ends (Top-down 动态规划+记忆化搜索 v.s. Bottom-up 动态规划)

    Description In the two-player game "Two Ends", an even number of cards is laid out in a ro ...

  2. POJ 1088 滑雪(记忆化搜索)

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 92384   Accepted: 34948 Description ...

  3. Codevs_1017_乘积最大_(划分型动态规划/记忆化搜索)

    描述 http://codevs.cn/problem/1017/ 给出一个n位数,在数字中间添加k个乘号,使得最终的乘积最大. 1017 乘积最大 2000年NOIP全国联赛普及组NOIP全国联赛提 ...

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

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

  5. 滑雪---poj1088(动态规划+记忆化搜索)

    题目链接:http://poj.org/problem?id=1088 有两种方法 一是按数值大小进行排序,然后按从小到大进行dp即可: #include <iostream> #incl ...

  6. POJ 1088 滑雪 DFS 记忆化搜索

    http://poj.org/problem?id=1088 校运会放假继续来水一发^ ^ 不过又要各种复习,功课拉下了许多 QAQ. 还有呀,就是昨天被一个学姐教育了一番,太感谢了,嘻嘻^ ^ 好了 ...

  7. POJ 1088 滑雪【记忆化搜索】

    题意:给出一个二维矩阵,要求从其中的一点出发,并且当前点的值总是比下一点的值大,求最长路径 记忆化搜索,首先将d数组初始化为0,该点能够到达的路径长度保存在d数组中,同时把因为路径是非负的,所以如果已 ...

  8. UVA_437_The_Tower_of_the_Babylon_(DAG上动态规划/记忆化搜索)

    描述 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  9. poj 1088 滑雪_记忆化搜索

    题意:略 直接用记忆化搜索就行了 #include<cstdio> #include<iostream> using namespace std; int n,m; int m ...

随机推荐

  1. 网站开发学习Python实现-Django学习-介绍(6.1.1)

    @ 目录 1.MVT 2.ORM 关于作者 1.MVT 主要的目的是为了快速,简便的开发数据库驱动的网站,强调代码的复用,多个组件可以很方便以插件的方式服务于整个框架,采用的是MVT设计模式(差不多的 ...

  2. MySQL(二):快速理解MySQL数据库索引

    索引 基本概念:索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现. 数据结构 Tree 指的是 Balance Tree,也就是平衡树.平衡树是一颗查找树,并 ...

  3. iOS音乐电台类项目开发

    1.技术难度不是太大,代码大致如下 2.用到的一些第三方 ZFProgressView,pageController,RESideMenu,MJRefresh,MBProgressHUD,RNFros ...

  4. Hyperledger fabric 链码篇GO(四)

    Hyperledger fabric 链码篇GO(四) fabric中的链码也就是我们区块链所认知的智能合约,fabric中可由nodejs,java,go编写,本篇只针对GO语言编写链码.将详细介绍 ...

  5. setTimeout 是到了xx ms 就执行吗,了解浏览器的 Event-Loop 机制

    要想 JavaScript 玩得溜,还得了解波 JavaScript 执行机制/(ㄒoㄒ)/~~. 个人博客:https://shansan.top 前言 最近看了波 JavaScript 相关的文章 ...

  6. vue3.0自定义指令(drectives)

    在大多数情况下,你都可以操作数据来修改视图,或者反之.但是还是避免不了偶尔要操作原生 DOM,这时候,你就能用到自定义指令. 举个例子,你想让页面的文本框自动聚焦,在没有学习自定义指令的时候,我们可能 ...

  7. java动态代理实现与原理详细分析(转)

    关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理. 一.代理模式    代理模式是常用的java设计模式, ...

  8. Linux下删除文件名带有空格的文件

    1.使用单引号将文件名括起来进行操作: rm '2018-08-07 17-29-48.png'

  9. File类的特点?如何创建File类对象?Java中如何操作文件内容,什么是Io流Io流如何读取和写入文件?字节缓冲流使用原则?

    重难点提示 学习目标 1.能够了解File类的特点(存在的意义,构造方法,常见方法) 2.能够了解什么是IO流以及分类(IO流的概述以及分类) 3.能够掌握字节输出流的使用(继承体系结构介绍以及常见的 ...

  10. linux系统搭建ftp服务器及创建用户使用

    linux 系统下搭建ftp服务器 ftp是什么 FTP是 File Transfer Protocol 文件传输协议的英文名称,用于在Internet上控制文件的双向传输. 同时它也是一个应用程序. ...