【動態規劃】練習題-滑雪問題

原題鏈接-滑雪

題目描述

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
一個人可以從某個點滑向上下左右相鄰四個點之一,當且僅當高度會減小。在上面的例子中,一條可行的滑坡爲 2424-1717-1616-11(從 2424 開始,在 11 結束)。當然 2525-2424-2323-\ldots…-33-22-11 更長。事實上,這是最長的一條。

輸入格式

輸入的第一行爲表示區域的二維數組的行數 RR 和列數 CC。下面是 RR 行,每行有 CC 個數,代表高度(兩個數字之間用 11 個空格間隔)。

輸出格式

輸出區域中最長滑坡的長度。

輸入輸出樣例
輸入 #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
輸出 #1
25

代碼題解
這個題百分之90完全是自己寫的,唯一有一個沒有通過,因爲超時了,參考了一下題解後改了就通過了。自己寫的那部分還是把我記憶化搜索的精髓,差點意思,後來重點標註了一下,關鍵地方要看dfs函數部分。

#include<iostream>
#include <algorithm>
using namespace std;

int r,c;
int a[1000][1000];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};//上下左右四個方向滑雪 

int f[1000][1000];
int cnt=0;
//記憶化搜索的方式 
//什麼是記憶化搜索? 就是說之前已經搜索過的值把他記錄下來,這樣就可以直接用了,不用重複搜索 

int dfs(int x,int y){
	if(f[x][y]) return f[x][y];//這裏檢查一下是不是之前在搜索的時候已經有數值了,有就直接返回不用再搜 
	for(int i=0;i<=3;i++)
	{
		if(a[x][y]>a[x+dx[i]][y+dy[i]]&& x+dx[i]>=1 && x+dx[i]<=r && y+dy[i]>=1&& y+dy[i]<=c)
		{
			dfs(x+dx[i],y+dy[i]);
			f[x][y]=max(f[x][y],f[x+dx[i]][y+dy[i]]+1);
			//對於當前這個點來說,有四個方向可供選擇,要選擇其中最佳的路徑,所以有這個狀態轉移方程		
		}
	}
	return f[x][y];
}

int main(){
	cin>>r>>c;
	for(int i=1;i<=r;i++)
	for(int j=1;j<=c;j++)
	cin>>a[i][j];
	
	for(int i=1;i<=r;i++)
	for(int j=1;j<=c;j++)
	   cnt=max(cnt,dfs(i,j));
	
	cout<<cnt+1;//結果爲啥要加1,因爲哪怕只有一個點也是有值的爲1,而前面初始化f[][]的時候值爲0,所以最後要加上 
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章