本文为原创,转载请注明: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. ubuntu 开启关闭mysql服务

    etc/init.d/mysql restart //重启 etc/init.d/mysql start //开启 etc/init.d/mysql stop //停止

  2. react第九单元(propTypes验证)

    第九单元(propTypes验证) #课程目标 理解类型验证的必要性 灵活掌握类型验证的使用 #知识点 在给react组件传属性的的时候,我们可以定义属性的类型,此时我们需要下载prop-types这 ...

  3. 是的,你没看错!Python可以实现自动化办公

    是的,你没看错!Python可以实现自动化办公 公众号[伤心的辣条],如今越来越多的人加入到学习Python的队伍当中,尤其是对于很多职场人来说,不管你是程序员还是非程序员,Python已经为很多职场 ...

  4. 【Go语言绘图】图片添加文字(二)

    这一篇将继续介绍gg库中绘制文字相关的方法,主要包括:DrawStringAnchored().DrawStringWrapped().MeasureMultilineString().WordWra ...

  5. 闭关修炼180天--手写持久层框架(mybatis简易版)

    闭关修炼180天--手写持久层框架(mybatis简易版) 抛砖引玉 首先先看一段传统的JDBC编码的代码实现: //传统的JDBC实现 public static void main(String[ ...

  6. python简单的函数应用

    一个简单的函数应用,包括自定义函数,lambda函数,列表解析. 1 #!usr/bin/env python3 2 # -*- coding:utf-8 -*- 3 4 #开始定义函数 5 def ...

  7. inotifywait命令如何监控文件变化?

    转载自:https://segmentfault.com/a/1190000038351925 文件监控可以配合rsync实现文件自动同步,例如监听某个目录,当文件变化时,使用rsync命令将变化的文 ...

  8. Stream并行流详解

    1.并行与并发的区别 在说到并行的时候,相信很多人都会想到并发的概念.那么并行和并发两者一字之差,有什么区别呢? 并行:多个任务在同一时间点发生,并由不同的cpu进行处理,不互相抢占资源 并行: 并发 ...

  9. JQuery生成二维码,有资源下载

    原文链接:http://www.yxxrui.cn/article/65.shtml 没时间或者懒得看的,可以直接看加粗部分(或试试手感▼). 使用jquery.qrcode来生成二维码,qrcode ...

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

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