【 POJ 1088】 滑雪 动态规划

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

滑雪

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 109909 Accepted: 41848

Description

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

Input

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

Output

输出最长区域的长度。

Sample Input

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

Sample Output

25

题意:就是有一个二维矩阵,让你求出最长下降子序列。

题解:其实笔者写这道题,也才开始学动态规划,也许是笔者天赋不行,这道题笔者想了三天。一开始我们还是先分析一下,如果从当前点滑下取得最优解,如果该点可以滑向周围下一点,那么下一点的最优解为当前点的最优解减1,如果不是,那么下一点存在另一个比当前最优解更优的解,那么+1就可以得到当前点更好的最优解,即当前点不是最优解,矛盾,故该问题满足最优子结构,对于重叠子问题,计算从某一点滑下的最优解一定算出周围4个点的最优解,对于每一点都是如此,有很多点都会被重回计算多次,故满足重叠子问题。写代码前,我们需要先考虑如何存储状态和状态转移,我们用dp[i][j]表示从第i行j列滑下取得最大高度,如果可以向周围4个点滑下,那么可以由4个点的最优解的最大值+1转移过来,由于算某个问题时,其子问题还没解决,所以我们需要使用带备忘录的自顶向下的递归。

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=100+7;
int a[maxn][maxn];   //存储地图
int dp[maxn][maxn];   //存储状态 dp[i][j] 表示从i行j列滑下的最大高度
int ans[maxn][maxn];   //存储每一个点的最优解
int n,m;
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};          //四个方向
int max(int x,int y)     //最大值函数
{
    if(x>y)return x;
    else return y;
}
int sk(int x,int y) 
{
    if(dp[x][y]>0)return dp[x][y];     //如果已经计算过子问题 直接返回子问题的解
    int sum=1;
    for(int i=0;i<4;i++){             //四个方向  写多个方向问题时 最好使用for循环 
        int nowx=x+dir[i][0];         //减少代码量
        int nowy=y+dir[i][1];
        if(nowx>=1&&nowx<=n&&nowy>=1&&nowy<=m&&a[x][y]>a[nowx][nowy])
        sum=max(sum,sk(nowx,nowy)+1);      //求当前点的最优解
    }
    dp[x][y]=sum;
    return sum;
}
int main()
{
    while(scanf("%d %d",&n,&m)==2){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%d",&a[i][j]);
                dp[i][j]=-1;
            }
        }
        int mx=-1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                ans[i][j]=sk(i,j);
                if(ans[i][j]>mx)mx=ans[i][j];
            }
        }
        printf("%d\n",mx);
    }
    return 0;
}

 

动态规划——滑雪(洛谷 P1434) 采用递推的方式求解 先用结构体保存每个点对应的原本坐标位置和高度; 将所有点按高度从小到大排序; 从第二个点开始求解(因为第一个点高度最低,显然滑行长度为1) 依次和它在原本坐标里的上下左右四个方向进行判断, 如果它比某一方向上的高度高,则它的滑行距离就应该是相比较的最大滑行距离+1和它保存的最大滑行距离 最后求完总共的点,进行遍历,得到最终最大值即可! 阅读详情

相关推荐

POJ1088 滑雪动态规划

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

淡然坊 8595

动态规划算法poj1088滑雪实验报告

动态规划算法poj1088滑雪实验报告 动态规划算法poj1088滑雪实验报告

poj1088 滑雪 动态规划+回溯

#include #include using namespace std; int num,n,m,a[1000][1000],d[1000][1000],maxx; int dp(int i,int j){ if(d[i][j]!=-1) return d[i][j]; if(i-1>=1&&a[i-1][j]<a[i][j]) d[i][j]=max(d[i][j],dp(i-1,j

. 1万+

Acwing.901 滑雪(动态规划)

一个人从滑雪场中的某个区域内出发,每次可以向上下左右任意一个方向滑动一个单位距离。当然,一个人能够滑动到某相邻区域的前提是该区域的高度低于自己目前所在区域的高度。现在给定你一个二维矩阵表示滑雪场各区域的高度,请你找出在该滑雪场中能够完成的最长滑雪轨迹,并输出其长度(可经过最大区域数)。矩阵中第i行第j列的点表示滑雪场的第i行第j列区域的高度。在给定矩阵中,一条可行的滑行轨迹为24-17-2-1。接下来R行,每行包含C个整数,表示完整的二维矩阵。给定一个R行C列的矩阵,表示一个矩形网格滑雪场。

qq_62235017的博客 422

滑雪动态规划

题目大意:给一个矩阵,矩阵里面的数表示相应位置的高度。滑雪只能由高处往低处滑,问一次性最多能滑过多少个点。 利用动态规划首先要注意:当前问题能由子问题推出来。子问题在前面已经解决过。 有一种巧妙的办法:如果我们将节点降序排序。以当前节点为尾巴,那么我们只要遍历比它更高的点,然后判断比它更高的点是不是它相邻的点,如果是,我们就要维护这个最大值:dp[i].path=max(dp[i].path,dp[j].path+1),由于i在j之后,所以一定比j点路程多1。(转移过程中用的是前缀) 然后我们记录整个过程中

weixin_52829980的博客 729

197、【动态规划】AcWing —— 901. 滑雪(C++版本)

整体思路就是依次进行递归遍历,从不同的起始位置出发找到一条最长区域路径。每次探寻时,从上下左右四个方向寻找,最终找到一条最长路径。,意为在已有的结果中和向上下左右某一个方向继续探索后,找到一个最大区域长度结果。dp[i][j] = 1,每个自身代表一个长度。位于(i, j)时,具有的最长区域路径长度。

STAR GAME 839

动态规划|AcWing 901. 滑雪

因此对于该题目,首先是理解怎么一回事,然后去体会记忆化递归的妙处,然后再去多做相似、相关类型的题目,对递归、计划化搜索熟悉后再回来看这道题,常看常新。使用二维数组记录,从某个点出发时的最长距离,这样当想要得知点(i,j)最长距离时,只要比较点(i,j)上下左右四个点哪个点最大即可。1.只能从高处向低处滑行,这个条件保证了从f(i,j)递归时不会重复走到f(i,j)。对于只学过一点算法的入门者而言,想要通过自己写出题解中的递归难度是非常大的。,想要通过这一道题完全掌握该题要考察的知识点是不可能的。

weixin_48118167的博客 377

POJ 1088滑雪动态规划

一。借鉴了两位大神的做法: 1.https://blog.csdn.net/huanghanqian/article/details/51646241 2.https://blog.csdn.net/Harington/article/details/86534326(第二位大神是3种做法,其中 我的做法是“我为人人”的思想)。 第一位大神还给了测试用例:(特别感谢) /* 测试数据 S...

爱学习的大白菜的博客 404

Poj 1088 滑雪(经典动态规划)

/**规划思想:DP[i][j] = Max{ DP[i-1][j], DP[i+1][j], DP[i][j-1], DP[i][j+1] } + 1;**/ #include <stdio.h> int r, c, map[101][101], dp[101][101],

小威的专栏 4365

滑雪 poj 1088动态规划

滑雪 poj 1088动态规划) Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 ...

菜菜的博客 642

POJ1088滑雪问题 简单dp(动态规划)已AC

滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 99422   Accepted: 37756 Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等

Link_Ray的博客 972

POJ1088】【动态规划滑雪问题 思路解析和代码

滑雪问题 题目链接 POJ不能解析#include<bits/stdc++.h> 个人思路 题意 input: 3 3 4 5 6 3 10 7 2 9 8 output:9 此题的最长的滑坡指的是滑坡的个数,每个格子代表一个滑坡,即从10开始出发,最长可以经过9个格子 错误思路1:一开始以为的是滑坡长度(数值)之和最大,此时输出为54 错误思路2:后来以为的是滑坡的出发点,此时输出为10 思路 整个思路可以类比最长下降子序列,与最长下降子序列相比,这个是二维的,且边界值并非dp[0][0]或d

九筒的博客 1087

poj 1088 滑雪(记忆化搜索/动态规划

程序设计实习动态规划作业 poj 1088 滑雪(记忆化搜索/动态规划

PKU_ZZY的博客 815

POJ 1088 滑雪 -- 动态规划

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

weixin_30311605的博客 69

poj 动态规划1088 滑雪

1088 滑雪

ziqi9216的博客 352

POJ 1088 Java:滑雪动态规划

这是一个动态规划问题(Dynamic programming):讲一个较大的问题分为若干的相互有关的子问题,即重叠子问题,使用递归的方法来求解。 对于这个问题来说,点A的步数为,与其相邻的四个点中高度低于A的点中,步数最长的点+1。 在计算每一个点的步数时,有些点的步数信息有可能会被重复使用,因此我们可以将每个点的步数信息计算出后存储,当再次需要时即可不必计算,直接调用。这就是记忆化搜索。

卡卡罗特 2222

POJ 1088 滑雪问题 动态规划

滑雪问题,用动态规划,计算出每个点作为起始点时的最长,注意计算的中间结果用矩阵保存,最后再所有路径中找出最长那条就是答案,要理解动态规划与递归的区别与联系#include using namespace std; int data[102][102],longetr[102][102]; int m,n; int cal(int i,int j){ int max = 0; if (longetr[i][j] > 0) //如果该点已经计算过直接返回路径长度,保存已有的计算结果这是动

Coding for Dreams 4205

滑雪 POJ 1088 动态规划

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 一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡

DaoCaoRen___的博客 248

poj 1088 滑雪 动态规划

滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 70183   Accepted: 25897 Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等

GodLike 1776
上一篇: 【HDU 1257】 最少拦截系统 动态规划
下一篇: 【 HDU 1087】 Super Jumping! Jumping! Jumping! 动态规划
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值