1. 程式人生 > 其它 >acwing 901. 滑雪

acwing 901. 滑雪

目錄

題目傳送門

題目描述

給定一個 RR 行 CC 列的矩陣,表示一個矩形網格滑雪場。

矩陣中第 ii 行第 jj 列的點表示滑雪場的第 ii 行第 jj 列區域的高度。

一個人從滑雪場中的某個區域內出發,每次可以向上下左右任意一個方向滑動一個單位距離。

當然,一個人能夠滑動到某相鄰區域的前提是該區域的高度低於自己目前所在區域的高度。

下面給出一個矩陣作為例子:

 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−2−124−17−2−1。

在給定矩陣中,最長的滑行軌跡為 25−24−23−…−3−2−125−24−23−…−3−2−1,沿途共經過 2525 個區域。

現在給定你一個二維矩陣表示滑雪場各區域的高度,請你找出在該滑雪場中能夠完成的最長滑雪軌跡,並輸出其長度(可經過最大區域數)。

輸入格式

第一行包含兩個整數 RR 和 CC。

接下來 RR 行,每行包含 CC 個整數,表示完整的二維矩陣。

輸出格式

輸出一個整數,表示可完成的最長滑雪長度。

資料範圍

1≤R,C≤3001≤R,C≤300,
0≤矩陣中整數≤100000≤矩陣中整數≤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

輸出樣例:

25

記憶化dfs

分析

記憶化搜尋!

程式碼

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring> 
using namespace std;
const int N = 310;
int n, m;
int f[N][N];
int g[N][N];
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

int dfs(int x, int y)
{
	int &v = f[x][y];
	if(v != -1) return v;
	
	// 遍歷四個方向
	v = 1; // 這個很重要!!! 
	for(int i = 0; i < 4; i++)
	{
		int nx = x + dx[i], ny = y + dy[i];
		
		if(nx >= 1 && nx <= n && ny >= 1 && ny <= m && g[x][y] > g[nx][ny])
		{
			v = max(v, dfs(nx, ny) + 1);
		}
		
	 } 
	
	return v;
 } 
 
 
 int main()
 {
 	scanf("%d%d", &n, &m);
 	for(int i = 1; i <= n; i++)
 		for(int j = 1; j <= m; j++)
 			scanf("%d", &g[i][j]);
 			
 			
 	memset(f, -1, sizeof f);
 	int res = 0;
 	for(int i = 1; i <= n; i++)
	 	for(int j = 1; j <= m; j++)
		{
		 	res = max(res, dfs(i, j));
//			printf("%d ", dfs(i, j));
		}
	cout << res << endl;
	return 0; 
 }

時間複雜度

\(O(n^2)\)

參考文章

https://www.acwing.com/activity/content/code/content/64186/