试题链接:https://vjudge.net/problem/POJ-1088
这道题肯定最先想到是DFS跟BFS,但是数据是100*100,还要每个点都进行搜索,肯定会超时。
但是我为了巩固DFS跟BFS,把这道题的BFS跟DFS都码了一遍,如果这道题数据没有这么大的话,肯定是可以的。
下面的代码是BFS跟DFS的代码,都TE了。
TE BFS
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <sstream>
#include <map>
#include <set>
#include <queue>
using namespace std;
int a[1005][1005];
int b[1005][1005];
int shu1[10]={0,1,-1,0,0};
int heng1[10]={0,0,0,1,-1};
struct sss
{
    int shu;
    int heng;
    int step;
}l;
int n,m;
int BFS(int x,int y)
{
    int ans=1;
    queue<sss>ss;
    ss.push({x,y,1});
    while(!ss.empty())
    {
        l=ss.front();
        ss.pop();
        ans=max(ans,l.step);
        for (int i=1;i<=4;i++)
        {
            int s=l.shu+shu1[i];
            int h=l.heng+heng1[i];
            if(s>0&&s<=n&&h>0&&h<=m)
            {
                if(a[s][h]<a[l.shu][l.heng]) ss.push(sss{s,h,l.step+1});
            }
        }
    }
    return ans;
}
int main ()
{

    cin >> n >> m;
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=m;j++)
        {
            cin >> a[i][j];
        }
    }
    for (int i=1;i<=n;i++)          //这一段可以跟下面的for循环结合,代码就会短很多。sum=max(sum,BFS(i,j)
    {
        for (int j=1;j<=m;j++)
        {
            b[i][j]=BFS(i,j);
        }
    }
    int sum=1;
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=m;j++)
        {
            sum=max(sum,b[i][j]);
        }
    }
    cout << sum << endl;
    return 0;
}

TL DFS
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <sstream>
#include <map>
#include <set>
#include <queue>
using namespace std;
int a[1005][1005];
int b[1005][1005];
int shu[10]={1,-1,0,0};
int heng[10]={0,0,-1,1};
int n,m,sum;
int DFS(int x,int y,int z)
{
    sum=max(sum,z);
    for (int i=0;i<=3;i++)
    {
        int s=x+shu[i];
        int h=y+heng[i];
        if(s>0&&s<=n&&h>0&&h<=m)
        {
            if(a[s][h]<a[x][y]) DFS(s,h,z+1);
        }
    }
    return sum;
}
int main ()
{

    cin >> n >> m;
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=m;j++)
        {
            cin >> a[i][j];
        }
    }
    for (int i=1;i<=n;i++)    //这一段可以跟下面的for循环结合,代码就会短很多,ans=max(ans,DFS(i,j,1)
    {
        for (int j=1;j<=m;j++)
        {
            sum=1;
            b[i][j]=DFS(i,j,1);
        }
    }
    int ans=1;
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=m;j++)
        {
            ans=max(ans,b[i][j]);
        }
    }
    cout << ans << endl;
    return 0;
}

下面的代码才是可以AC的代码,也是每一个点都进行遍历,找他四周的点,如果比他小的话,就递归再次进行遍历,最后记录下来这个点的最大二维下降子序列的长度。
如果比他小的那个点在上述步骤中已经遍历过了,则直接用他记录下来的值就可以了,这样就减少了时间复杂度,不会被超时。

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[105][105];
int b[105][105];
int shu1[10]={0,1,-1,0,0};
int heng1[10]={0,0,0,1,-1};
int n,m;
int DP(int x,int y)
{
    int sum=0;
    if(b[x][y]!=0)        //遍历结束的条件
    {
        return b[x][y];
    }
    for (int i=1;i<=4;i++)
    {
        int s=x+shu1[i];
        int h=y+heng1[i];
        if(a[s][h]<a[x][y]&&s>0&&s<=n&&h>0&&h<=m)
        {
            sum=max(sum,DP(s,h));
        }
    }
    b[x][y]=sum+1;
    return b[x][y];
}
int main ()
{
    cin >> n >> m;
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=m;j++)
        {
            cin >> a[i][j];
        }
    }
    int ans=1;
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=m;j++)
        {
            ans=max(ans,DP(i,j));
        }
    }
    cout << ans << endl;
    return 0;
}