题解[SHOI2002]滑雪

题目传送门
此题有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的越狱

猜你喜欢

转载自www.cnblogs.com/LJA001100/p/10359273.html
今日推荐