《Head First 設計模式》:工廠方法模式
阿新 • • 發佈:2020-07-21
[SHOI2002]滑雪
題目描述
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-11\)
輸入格式
輸入的第一行為表示區域的二維陣列的行數 \(R\) 和列數 \(C\)。下面是 \(R\) 行,每行有 \(C\) 個數,代表高度(兩個數字之間用 \(1\) 個空格間隔)。
輸出格式
輸出區域中最長滑坡的長度。
輸入輸出樣例
輸入 #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
說明/提示
對於\(100\%\)的資料\(1≤R,C≤100\)
這是一道比較經典的記憶化搜尋,
剛開始呢,我寫了一個很迷的搜尋,
果不其然,TLE了一個,
神奇的是,WA了兩個???
然後我又寫了一個搜尋,
只T了一個,(其實我已經寫好了記憶化,只不過把記憶化註釋掉了)
然後去掉註釋,完美的AC了。
#include<cstdio> #include<algorithm> using namespace std; int r,c,a[101][101],ans,dp[101][101]; int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; int dfs(int x,int y){ if(dp[x][y]) return dp[x][y]; int sum=0; for(int i=0;i<4;i++){ int xx=x+dx[i],yy=y+dy[i]; if(xx>=1&&xx<=r&&yy>=1&&yy<=c&&a[xx][yy]<a[x][y]){ sum++; dp[x][y]=max(dp[x][y],sum+dfs(xx,yy)); sum--; } } return dp[x][y]; } int main(){ scanf("%d%d",&r,&c); for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) scanf("%d",&a[i][j]); for(int i=1;i<=r;i++) for(int j=1;j<=c;j++){ dfs(i,j); ans=max(ans,dp[i][j]); } printf("%d",ans+1); return 0; }
其實記憶化不難,
只是我一般都用void寫搜尋(也不知道為啥
但是記憶化得用int,
就弄得我很懵,
然後就沒有然後了,
記憶化還是比較好理解的,
只是在DFS的基礎上加了一個特判,
如果這個點走過,
就直接返回這個點的值。
本蒟蒻撤了qwq