动态规划VS记忆化搜索(2)

luoguP1434滑雪

题目描述

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(从 24 开始,在 1 结束)。当然 25-24-23-······-3-2-1 更长。事实上,这是最长的一条。

输入格式

输入的第一行为表示区域的二维数组的行数 R 和列数 C。下面是 R行,每行有 C$个数,代表高度(两个数字之间用 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

输出

25

说明/提示

对于 100% 的数据,1<=R,C<=100。

还是这道题,记忆化搜索已经讲完了他的题目解法,见(1)中的题目做法,但两种算法的PK仍然在继续,因为动态规划还没有出场!

有请动态规划!

记忆化搜索和我十分相似,甚至我们两个可以互相替代,我的时间更短,所以记忆化搜索应该输在我手上。至于这题,我的方法需要两个辅助,堆和opreator.

operator是一个提供运算符重载的东西,他较为复杂,常用于struct或class,本人喜欢用struct。

cpp 复制代码
struct node{
    int x,y,val;
    bool operator>(const node& o)const{
        return val>o.val;
    }
};

由于代码过于难,我也调了一天,就不让你们痛苦了。

堆也很简单,stl大法好!

cpp 复制代码
priority_queue<node,vector<node>,greater<node> >q;

输入时要把该点高度扔进堆里,初始化dp[i][j]=1。

重头戏在dp,dp无后效性,所以要从小到大进行 dp,由于dp[i][j]的定义是在i,j这个点做滑雪起点时能滑的最大坡,所以从小到大的顺序不会有后效性。然后维护方向数组,像搜索一样扩展。

代码如下:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
struct node{
    int x,y,val;
    bool operator>(const node& o)const{
        return val>o.val;
    }
};
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int a[1001][1001],n,dp[1001][1001],m;
priority_queue<node,vector<node>,greater<node> >q;
int main(){
	cin>>n>>m;
	for (int i=1;i<=n;i++){
		for (int j=1;j<=m;j++){
			cin>>a[i][j];
			q.push({i,j,a[i][j]});
			dp[i][j]=1;
		}
	}
	while (q.size()){
		int x=q.top().x,y=q.top().y,val=q.top().val;
		q.pop();
		int k=dp[x][y];
		for (int i=0;i<4;i++){
			int xx=dx[i]+x,yy=dy[i]+y;
			if (val>a[xx][yy]){
				dp[x][y]=max(dp[x][y],k+dp[xx][yy]);
			}
		}
	}
	int ans=0;
	for (int i=1;i<=n;i++){
		for (int j=1;j<=m;j++){
			ans=max(ans,dp[i][j]);
		}
	}
	cout<<ans<<endl;
    return 0;
}

(如果有误在评论区留言即可)

相关推荐
无限进步_10 小时前
【C++&string】大数相乘算法详解:从字符串加法到乘法实现
java·开发语言·c++·git·算法·github·visual studio
苏纪云10 小时前
蓝桥杯考前突击
c++·算法·蓝桥杯
W230357657310 小时前
经典算法详解:最长公共子序列 (LCS) —— 从暴力递归到动态规划完整实现
算法·动态规划·最长子序列
pzx_00110 小时前
【优化器】 随机梯度下降 SGD 详解
人工智能·python·算法
小肝一下10 小时前
每日两道力扣,day8
c++·算法·leetcode·哈希算法·hot100
无限进步_11 小时前
【C++】验证回文字符串:高效算法详解与优化
java·开发语言·c++·git·算法·github·visual studio
Meme Buoy11 小时前
18.补充数学1:生成树-最短路径-最大流量-线性规划
数据结构·算法
paeamecium11 小时前
【PAT甲级真题】- Count PAT‘s (25)
c++·算法·动态规划·pat考试·pat
汀、人工智能11 小时前
[特殊字符] 第89课:岛屿数量
数据结构·算法·数据库架构·图论·bfs·岛屿数量
九英里路11 小时前
cpp容器——string模拟实现
java·前端·数据结构·c++·算法·容器·字符串