嗯。我又无聊的来写ACM了,就当是玩玩好了,对,还是ACM好玩。
题目给出一个山势图,用于滑雪,人可以从高的地方滑到四个方向中低的地方。求最长的滑雪线路,地图尺寸最大为100*100。
首先地图有一万个格子,如果每个起点进行搜索都进行强制深搜,其实可能有点慢(不过看题目也就一个测试用例,估计慢点也能接受)。考虑到一个起点p,如果周围的起点,最长路径长度已知,那么这个起点的最长路径必然满足
max_len(p) = max(1 + max_len(p_round)), p_round为p点周围任意一个p可以到达的点
所以可以考虑使用动态规划来整这个,用一个dp数组,记录某个点是否搜过,没搜过为0,需要进行搜索,然后将得到的结果计入该点。遍历所有起点,即可得到答案。
#include <iostream>
#include <string.h>
using namespace std;
int mountain[105][105];
int dp[105][105];
int c,r;
int dir[4][2] = {{-1,0}, {1,0},{0,-1},{0,1}};
bool check(int x, int y)
{
if(x < 0 || y < 0)
{
return false;
}
if(x >= c || y >= r)
{
return false;
}
return true;
}
int cal_min_for_one_block(int x, int y)
{
if(!check(x, y))
{
return 0;
}
if(dp[x][y] == 0)
{
//should cal
for (int i = 0; i < 4; ++i) {
int nextX = x + dir[i][0];
int nextY = y + dir[i][1];
if(check(nextX, nextY) && mountain[x][y] > mountain[nextX][nextY])
{
dp[x][y] = std::max(dp[x][y], cal_min_for_one_block(nextX, nextY));
}
}
dp[x][y] += 1;
}
//cout << x << "," << y << ":" << mountain[x][y] << "," << dp[x][y] << endl;
return dp[x][y];
}
int cal_min()
{
int ret = 0;
for (int i = 0; i < c; ++i) {
for (int j = 0; j < r; j++) {
ret = std::max(ret, cal_min_for_one_block(i,j));
}
}
return ret;
}
int main(int argc, char *argv[])
{
memset(mountain, 0, sizeof(mountain));
memset(dp, 0, sizeof(dp));
cin >> c >> r;
for (int i = 0; i < c; ++i) {
for (int j = 0; j < r; j++) {
cin >> mountain[i][j];
}
}
cout << cal_min() ;
return 0;
}