题目传送门
此题有2种解法,DP和记忆化搜索
我写完代码,也不知道自己用的是哪种
应该是DP和记忆化的结合体吧
状态转移方程: f[i][j] = max(f[i+1][j]+1,f[i-1][j]+1,f[i][j+1]+1,f[i][j-1]+1) (在高度下降的前提下)
代码如下
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int inf = 2147483647;
int maps[120][120];
int l[120][120];//即为f数组,代表从一个点出发的最长滑道长度
int ans = -1;
inline int quickread(){
char ch = getchar();
int x = 0;
while(ch<'0'||ch>'9'){
ch = getchar();
}
while('0'<=ch&&ch<='9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x;
} //快读优化
void gt(int x,int y){ /确定l[x][y]
if(l[x][y]!=-1)return;
if(x<1||x>n||y<1||y>m)return;
l[x][y] = 1;
//向四个方向寻找滑道的下一个点
if(maps[x+1][y]<maps[x][y]){
if(l[x+1][y]==-1)gt(x+1,y);
//注意,如果l[x+1][y]还未确定的话,需先确定l[x+1][y]
l[x][y]=max(l[x][y],l[x+1][y]+1);
}
if(maps[x-1][y]<maps[x][y]){
if(l[x-1][y]==-1)gt(x-1,y);
l[x][y]=max(l[x][y],l[x-1][y]+1);
}
if(maps[x][y+1]<maps[x][y]){
if(l[x][y+1]==-1)gt(x,y+1);
l[x][y]=max(l[x][y],l[x][y+1]+1);
}
if(maps[x][y-1]<maps[x][y]){
if(l[x][y-1]==-1)gt(x,y-1);
l[x][y]=max(l[x][y],l[x][y-1]+1);
}
if(ans<l[x][y])ans = l[x][y];
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 1;i<=n;i++)
for(int j = 1;j<=m;j++)
maps[i][j] = quickread();
memset(l,-1,sizeof(l));
for(int i = 1;i<=n;i++)
for(int j =1;j<=m;j++) gt(i,j);
printf("%d",ans);
return 0;
}
第2道省选题,第一道是HNOI2008的越狱