本文为原创,转载请注明: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. MySQL锁(四)行锁的加锁规则和案例

    在上一篇文章,我们学习了间隙锁和next-key lock,但是不知道怎么加锁,有哪些规则.间隙锁的概念不太好理解,尤其是配合上行锁后,很容易在判断是否会出现锁等待的问题上犯错. 今天我们就来学习一下 ...

  2. UWP ListView添加不同样式

    先看效果: 使用ListView的ItemTemplateSelector <ListView IsItemClickEnabled="True" ItemContainer ...

  3. 学习JUC源码(3)——Condition等待队列(源码分析结合图文理解)

    前言 在Java多线程中的wait/notify通信模式结尾就已经介绍过,Java线程之间有两种种等待/通知模式,在那篇博文中是利用Object监视器的方法(wait(),notify().notif ...

  4. OSPF --- 不规则区域实验

    OSPF不规则区域实验: 一.知识点整理: OSPF中路由器的角色(看图): 骨干路由器:路由器所有接口属于area 0  -->R3 非骨干路由器:路由器所有接口属于非area 0  --&g ...

  5. CCNP之OSPF实验报告

    OSPF实验报告 一.实验要求 1.R4为ISP,其上只能配置IP地址:R4与其它所有直连设备间使用公有IP2.R3--R5/6/7为MGRE环境,R3为中心站点3.整个OSPF环境IP地址为172. ...

  6. ASP.NET Core 3.1 IOC容器以及默认DI以及替换Autofac生命周期

    IOC 就是我们需要一个对象 以前我们是去 new 现在我们是直接向 IOC容器 要我们需要的那个对象. 使用一个IOC容器(autofac)通过依赖注入控制各个组件的耦合.也就是说你写好了组件,不需 ...

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

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

  8. MethodHandleVS反射

    Method Handle与反射 如无特殊说明,本文所有代码均基于JDK1.8.0_221 Method Handle入门 反射我们都知道,为我们提供了运行时对类的成员方法访问的手段,极大地提高了Ja ...

  9. 算法竞赛入门经典第二版第一章习题-(练习Java和C++语法)

    习题1-1 平均数(average) 输入三个整数,输出他们的平均值,保留三位小数 Java: package suanfa; import java.util.Scanner; public cla ...

  10. [leetcode349]Intersection of Two Arrays

    设计的很烂的一道题 List<Integer> res = new ArrayList<>(); // int l1 = nums1.length; // int l2 = n ...