1. 程式人生 > >【QAQ】codevs滑雪和記憶化搜尋的小經驗

【QAQ】codevs滑雪和記憶化搜尋的小經驗

戳我←

題目描述 Description

trs喜歡滑雪。他來到了一個滑雪場,這個滑雪場是一個矩形,為了簡便,我們用r行c列的矩陣來表示每塊地形。為了得到更快的速度,滑行的路線必須向下傾斜。
例如樣例中的那個矩形,可以從某個點滑向上下左右四個相鄰的點之一。例如24-17-16-1,其實25-24-23…3-2-1更長,事實上這是最長的一條。

輸入描述 Input Description

輸入檔案

第1行: 兩個數字r,c(1<=r,c<=100),表示矩陣的行列。
第2..r+1行:每行c個數,表示這個矩陣。

輸出描述 Output Description

輸出檔案

僅一行: 輸出1個整數,表示可以滑行的最大長度。

樣例輸入 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

第一次打了個手打佇列的寬搜,居然A了四個點嘿嘿嘿嘿嘿

orz57級wzd和wyh兩個DP大佬

第一道記憶化搜尋的題目。

思路是以每一個點為起點進行dfs,用dp陣列記錄下每次搜到的最長路

一開始傻傻的認為不同起點時搜到的每個點的最長路是不一樣的QAAAQ

嘛,遞迴就是相同的過程一層層算下去

既然一開始要求最優解的話,那程式得到的每一層結果也一定是最優的

也可以理解成滑到那裡忽然翻車了滑到的最長路徑是多少23333

這樣,當搜到一個節點,發現已經搜到過他的最長路,那就直接呼叫

已經知道翻車前最多滑多遠了,爬起來繼續滑還能滑多遠呢23333

#include<iostream>
#include<cstdio>
using namespace std;
const int MAXN = 1000 + 1;
int map[MAXN][MAXN],dp[MAXN][MAXN],maxx;
int mu[] = {0,-1,1,0},
    mr[] = {1,0,0,-1};
int dfs(int k,int j)
{
    if
(dp[k][j]) return dp[k][j]; int ans = 1; for(int i = 0; i < 4; i ++) { int x = k + mu[i] ; int y = j + mr[i] ; if(map[x][y] > map[k][j]) ans = max(ans, dfs(x, y) + 1); } return dp[k][j] = ans; } int m,n; int main() { cin >> m >> n; for(int i = 1; i <= m; i ++) for(int j = 1; j <= n;j ++) cin >> map[i][j]; for(int i = 1; i <= m; i ++) for(int j = 1; j <= n;j ++) { dp[i][j] = max(dfs(i,j),dp[i][j]); maxx = max(maxx, dp[i][j]); } cout << maxx; return 0; }