POJ 2111 DP+记录路径

题意:
这里写图片描述
思路:
类似滑雪

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 444
int n,ans=-1,s[N*N],map[N][N],cnt,f[N][N],xx[]={2,2,1,1,-1,-1,-2,-2},yy[]={1,-1,2,-2,2,-2,1,-1};
struct Node{int x,y,w;Node(){}Node(int xx,int yy,int ww){x=xx,y=yy,w=ww;}}node[N*N],move[N][N],jy;
bool cmp(Node a,Node b){return a.w>b.w;}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            scanf("%d",&map[i][j]),node[++cnt]=Node(i,j,map[i][j]);
    sort(node+1,node+1+cnt,cmp);
    for(int i=1;i<=cnt;i++)
        for(int j=0;j<8;j++){
            int tx=node[i].x+xx[j],ty=node[i].y+yy[j];
            if(tx<=0||ty<=0||tx>n||ty>n||map[tx][ty]>map[node[i].x][node[i].y])continue;
            if(f[tx][ty]<f[node[i].x][node[i].y]+1){
                f[tx][ty]=f[node[i].x][node[i].y]+1;
                move[tx][ty]=Node(node[i].x,node[i].y,node[i].w);
            }
            else if(f[tx][ty]==f[node[i].x][node[i].y]+1&&move[tx][ty].w>node[i].w)
                move[tx][ty]=Node(node[i].x,node[i].y,node[i].w);
            if(ans<f[tx][ty])ans=f[tx][ty],jy=Node(tx,ty,map[tx][ty]);
            else if(ans==f[tx][ty]&&jy.w>map[tx][ty])jy=Node(tx,ty,map[tx][ty]);
        }
    if(!jy.w){
        int minn=0x3fffffff;
        for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)minn=min(minn,map[i][j]);
        printf("1\n%d\n",minn);return 0;
    }
    while(1){
        s[++s[0]]=jy.w;
        if(!f[jy.x][jy.y])break;
        jy=move[jy.x][jy.y];
    }
    for(int i=0;i<=s[0];i++)printf("%d\n",s[i]);
}

这里写图片描述

转载于:https://www.cnblogs.com/SiriusRen/p/6532186.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值