暴搜
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 6 int num[505][505]; 7 int Ans=1,n,m; 8 int fx[4]={0,0,1,-1}; 9 int fy[4]={1,-1,0,0}; 10 11 void dfs(int x,int y,int len){ 12 Ans=max(Ans,len); 13 for (int i=0;i<4;i++) 14 if (num[x][y]>num[x+fx[i]][y+fy[i]]&&num[x+fx[i]][y+fy[i]]!=-1) 15 dfs(x+fx[i],y+fy[i],len+1); 16 } 17 18 int main(){ 19 freopen("ski.in","r",stdin); 20 freopen("ski.out","w",stdout); 21 scanf("%d%d",&n,&m); 22 memset(num,-1,sizeof(num)); 23 for (int i=1;i<=n;i++) 24 for (int j=1;j<=m;j++) 25 scanf("%d",&num[i][j]); 26 for (int i=1;i<=n;i++) 27 for (int j=1;j<=m;j++){ 28 bool is_ok=0; 29 for(int t=0;t<=3;t++) 30 if (num[i][j]>num[i+fx[t]][j+fy[t]]&&num[i+fx[t]][j+fy[t]]!=-1) is_ok=1; 31 if (is_ok==1) dfs(i,j,1); 32 } 33 printf("%d",Ans); 34 return 0; 35 }
直接搜索无法很好的处理重叠子问题,因此可采用记忆化搜索以减少时间
记忆化搜索
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std; 5 6 int f[505][505];//存储从(i,j)出发可滑的最长路径,避免重复搜索 7 int num[505][505]; 8 int fx[4]={0,0,1,-1}; 9 int fy[4]={1,-1,0,0}; 10 11 int dfs(int x,int y){ 12 int tmp=0; 13 if (f[x][y]!=-1) return f[x][y]; 14 for (int i=0;i<4;i++){ 15 if (num[x][y]>num[x+fx[i]][y+fy[i]]&&num[x+fx[i]][y+fy[i]]!=-1) 16 tmp=max(tmp,dfs(x+fx[i],y+fy[i])+1); 17 } 18 if (tmp==0) { 19 f[x][y]=1; 20 return 1; 21 } 22 f[x][y]=tmp; 23 return tmp; 24 } 25 int main(){ 26 int ans=1; 27 freopen("ski2.in","r",stdin); 28 freopen("ski2.out","w",stdout); 29 int n,m; 30 scanf("%d%d",&n,&m); 31 memset(num,-1,sizeof(num)); 32 memset(f,-1,sizeof(f)); 33 for (int i=1;i<=n;i++) 34 for (int j=1;j<=m;j++) 35 scanf("%d",&num[i][j]); 36 for (int i=1;i<=n;i++) 37 for (int j=1;j<=m;j++) 38 ans=max(ans,dfs(i,j)); 39 printf("%d ",ans); 40 return 0; 41 }