洛谷 P1434 [SHOI2002]滑雪
这道题适合记忆化练手
毕竟总有些大佬虐题。
这个题有几个剪枝
1.记忆化
这个不用多说了吧
剪枝就是
如果 当前点到下面一个点的目前下降的高度+1 小于 下面那个点 能下降的高度
那么反过来,这个点不也有更大的值吗
既然这样的话,又可以得出
这个点不是最优解了,因为另外一条路线已经滑了更大的一个高度了,剩下高度相同,你觉得哪个滑的高
举例: 已知a>b 那么必然的,a+c>b+c
2.从高到低枚举起点。
可以肯定的是,目前选择的这个点的高度已经是这次dfs最大能够滑雪的高度了,如果有比这个高的答案,那么我们已经得到了而且后面不会有比这个高的答案了,所以后面的剪枝都不用做了
这个剪枝优化前的效果:
优化后:
懂了吧,上代码
#include<iostream> #include<cmath> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; int n,m; struct p{ int x,y,height; }; int a[120][120]; int dx[]={0,0,1,-1}; int dy[]={1,-1,0,0}; p s[12000]; int f[120][120]; int mmx=1; int cmp(p a,p b) { return a.height>b.height; //sort: <则为从小到大 >则为从大到小 } void dfs(int x,int y) { for(int i=0;i<=3;i++) { int nx,ny; nx=x+dx[i]; ny=y+dy[i]; if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&a[x][y]>a[nx][ny]) //判断是否越界以及能否走到那个点 { if(f[nx][ny]<f[x][y]+1) { f[nx][ny]=f[x][y]+1; mmx=max(f[nx][ny],mmx); dfs(nx,ny); } } } return ; } int main() { scanf("%d %d",&n,&m); int i,j; int tot=0; for(i=1;i<=n;i++) for(j=1;j<=m;j++) { f[i][j]=1; scanf("%d",&a[i][j]); s[++tot].height=a[i][j]; s[tot].x=i; s[tot].y=j; } sort(s+1,s+tot+1,cmp); //做一遍sort得到从高到低的位置(点) for(i=1;i<=tot;i++) { dfs(s[i].x,s[i].y); if(tot-i+1<mmx) break; } printf("%d",mmx); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?