立志成为饮水机!

洛谷 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;
}
复制代码

 

posted @   寒冰大大  阅读(360)  评论(0编辑  收藏  举报
编辑推荐:
· 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,谁才是开发者新宠?
点击右上角即可分享
微信分享提示