https://vjudge.net/problem/UVA-10285
题目大意:给出一张n*m的雪地地图,每格标注的是该点的高度。从地势高的地方可以滑到地势低的地方(只能上下左右滑),问最长的滑雪距离。
解题思路:逐一访问各点,若该点没有被访问过,看看周围各个点比这个点小的,且已经计算过的,取得这些值的最大并+1.
记忆化DP.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
#define MAX 105
int d[MAX][MAX];
int vist[MAX][MAX];
int xx[]= {1,-1,0,0};
int yy[]= {0,0,-1,1};
int main() {
int t,n,m;
string s;
cin>>t;
while(t--) {
cin>>s;
cin>>n>>m;
memset(vist,0,sizeof(vist));
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
cin>>d[i][j];
}
}
bool isEx=false;
int imax,k,allmax=0;
do {
isEx=false;
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
if(vist[i][j]) continue;
imax=1;
for(k=0; k<4; k++) {
//如果出界
if(i+yy[k]<0||i+yy[k]>=n||j+xx[k]<0||j+xx[k]>=m) continue;
//如果大于等于中心点
if(d[i][j]<=d[i+yy[k]][j+xx[k]]) continue;
//如果小于中心,但是还没有计算
if(d[i][j]>d[i+yy[k]][j+xx[k]]&&!vist[i+yy[k]][j+xx[k]]) break;
imax=max(imax,vist[i+yy[k]][j+xx[k]]+1);
}
if(k==4) {
vist[i][j]=imax;
isEx=true;
allmax=max(allmax,imax);
}
}
}
} while(isEx);
cout<<s<<": "<<allmax<<endl;
}
}
别人的解法dp https://blog.csdn.net/u014664226/article/details/46686127
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#define eps 1e-6
#define LL long long
using namespace std;
const int maxn = 100 + 5;
const int INF = 0x3f3f3f3f;
const int dx[] = {0, -1, 0, 1};
const int dy[] = {1, 0, -1, 0};
int r, c;
int G[maxn][maxn], d[maxn][maxn];
string name;
int dp(int x, int y) {
if(d[x][y] != -1) return d[x][y];
d[x][y] = 1;
for(int i = 0; i < 4; i++)
if(x+dx[i] >= 1 && x+dx[i] <= r
&& y+dy[i] >= 1 && y+dy[i] <= c
&& G[x][y] > G[x+dx[i]][y+dy[i]])
d[x][y] = max(d[x][y], dp(x+dx[i], y+dy[i])+1);
return d[x][y];
}
void init() {
memset(d, -1, sizeof(d));
cin >> name >> r >> c;
for(int i = 1; i <= r; i++)
for(int j = 1; j <= c; j++)
cin >> G[i][j];
}
void solve() {
int ans = 0;
for(int i = 1; i <= r; i++)
for(int j = 1; j <= c; j++) ans = max(ans, dp(i, j));
cout << name << ": " << ans << endl;
}
int main() {
//freopen("input.txt", "r", stdin);
int n;
cin >> n;
while(n--) {
init();
solve();
}
return 0;
}