poj1088
解题思路
dp[i][j]:代表从坐标(i,j)出发的最大长度
则:
dp[i,j]=1+max{ dp[i-1,j], dp[i+1,j], dp[i,j-1], dp[i,j+1]}
即搜素(i,j)的上下左右四个方向,找出最长。
注意情况:
我们应该关注计算的顺序。如果,按照一行一行的来,会发现,自底向上计算的时候,一些没有计算过。所以,这个顺序是不行的。那只能换个思路,通过思考我们可以知道,在计算最小值的时候,h[i][j]的时候,更小的值没有,就可认为是已经知道的,然后再计算次小的,就是最小的已知,可计算。则可知,需要对高度进行排序
代码:
#include<stdio.h>
#include<iostream>
using namespace std;
int dp[101][101] = { 0 };
int r[101][101] = { 0 };
int search(int i, int j, int m, int n)//以节点(i,j)为起点的最长长度
{
if (r[i][j]) //该值存在,则返回
return r[i][j];
int temp[4] = { 0 }; //用来保存
//一定要初始化
int max = 0;
if ((i + 1 < m) && (dp[i + 1][j] < dp[i][j]))
temp[0] = search(i + 1, j, m, n);
if ((i - 1 >= 0) && (dp[i - 1][j] < dp[i][j]))
temp[1] = search(i - 1, j, m, n);
if ((j + 1 < n) && (dp[i][j+1] < dp[i][j]))
temp[2] = search(i,j+1, m, n);
if ((j - 1 >= 0) && (dp[i][j-1] < dp[i][j]))
temp[3] = search(i,j-1, m, n);
for (int k = 0; k < 4; k++)
{
if (temp[k] > max)
max = temp[k];
}
r[i][j] = max + 1;
return r[i][j];
}
int main()
{
int i, j, m, n;
while ((cin >> m) && (cin >> n))
{
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
r[i][j] = 0;//初始化
cin >> dp[i][j];
}
}
int max = 0, temp;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
temp = search(i, j, m, n);//求以每个节点为起点的最长长度
if (temp > max)
max = temp;
}
}
cout << max << endl;
}
return 0;
}

浙公网安备 33010602011771号