Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 93921 | Accepted: 35555 |
Description
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。當然25-24-23-...-3-2-1更長。事實上,這是最長的一條。
Input
Output
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
每個點上下左右搜索即可,算得上優化版的暴力,但歸類是DP
按數值從小到大排序,然後依次上下左右搜索
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e2+10;
int map[maxn][maxn], dp[maxn][maxn];
int mov[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int ans, n, m, T;
struct node{
int x, y, val;
bool operator < (const node& a) const{
return val < a.val;
}
}M[maxn*maxn];
void DP(){
for(int c = 0; c < T; c++){
int i, j, x, y;
x = M[c].x;
y = M[c].y;
for(int v = 0; v < 4; v++){
i = x + mov[v][0];
j = y + mov[v][1];
if(i >= 0 && i < n && j >= 0 && j < m && map[x][y] > map[i][j]) dp[x][y] = max(dp[i][j]+1, dp[x][y]);//開始是按小於號來比較的,後來發現不對,小於號比較的是下一順位,若是不連續就會出錯,只能用大於號來動態規劃當前值
ans = max(ans, dp[x][y]);
}
}
}
int main(){
int t;
T = ans = 0;
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
scanf("%d", &map[i][j]);
dp[i][j] = 1;
M[T].x = i;
M[T].y = j;
M[T++].val = map[i][j];
}
}
sort(M, M+T);
DP();
printf("%d\n", ans);
return 0;
}