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;
 }
posted @ 2020-11-07 15:32  Quella'  阅读(64)  评论(0)    收藏  举报
Live2D