題目地址:http://acm.nyist.net/JudgeOnline/problem.php?pid=10
這道題就是找出一條最長連續遞減序列,並求出其長度。可以用記憶化深搜,求出每一點最長序列的長度,然後求最大值即可。
代碼如下:
#include<iostream>
#include<cstring>
using namespace std;
const int N=105;
int a[N][N],m,n,f[N][N];
inline int max(int a,int b)
{
return a>b?a:b;
}
inline int max(int a,int b,int c,int d)//求四個數的最大值
{
return max(max(a,b),max(c,d));
}
int d(int x,int y,int h)//x,y爲座標,h爲前一個位置的高度
{
if(x==0||y==0||x>m||y>n||a[x][y]>=h)//當到達邊界,或當前位置高度不小於前一個時返回0
return 0;
if(f[x][y]>=0)//若f[x][y]計算過,直接返回
return f[x][y];
//遞歸求出此點的最大長度,保存在f[x][y]並返回
f[x][y]=max(d(x+1,y,a[x][y]),d(x,y+1,a[x][y]),d(x-1,y,a[x][y]),d(x,y-1,a[x][y]))+1;
return f[x][y];
}
int main()
{
int t;
cin>>t;
while(t--)
{
int i,j,k,maxi=-0xffff;
cin>>m>>n;
memset(f,-1,sizeof(f));
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
cin>>a[i][j];
for(i=1;i<=m;i++)//求出每一點的最長序列,並不斷更新最大值
for(j=1;j<=n;j++)
{
k=d(i,j,0xffff);
if(maxi<k)
maxi=k;
}
cout<<maxi<<endl;
}
return 0;
}