• POJ 2111


    记忆化搜索即可,设DP[I][J]为可到达的最大步数。

    输出时用了一种较笨拙的方法,还有一种方法是使用最长上升子序列的方式,挺好,先排序,这让我想起上次BESTCODER的一题

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    const int N=370;
    struct {
    	int x,y;
    }que[N*N],dir[8];
    int num[N][N];
    int dp[N][N];
    int n,tf,f,l;
    
    bool ok(int x,int y,int i,int j){
    	if(x>=1&&x<=n&&y>=1&&y<=n){
    		if(num[x][y]>num[i][j])
    		return true;
    	}
    	return false;
    }
    
    void dfs(int i,int j){
    	int tx,ty;
    	if(dp[i][j]!=-1) return ;
    	dp[i][j]=1;
    	for(int k=0;k<8;k++){
    		tx=i+dir[k].x;
    		ty=j+dir[k].y;
    		if(ok(tx,ty,i,j)){
    			dfs(tx,ty);
    			if(dp[i][j]==-1||dp[tx][ty]+1>dp[i][j])
    			dp[i][j]=dp[tx][ty]+1;
    		}
    	}
    }
    
    int main(){
    	dir[0].x=2,dir[0].y=1;dir[1].x=2,dir[1].y=-1;
    	dir[2].x=-2,dir[2].y=1;dir[3].x=-2,dir[3].y=-1;
    	dir[4].x=1,dir[4].y=2; dir[5].x=-1;dir[5].y=2;
    	dir[6].x=1,dir[6].y=-2;dir[7].x=-1,dir[7].y=-2;
    	while(scanf("%d",&n)!=EOF){
    		for(int i=1;i<=n;i++){
    			for(int j=1;j<=n;j++){
    				scanf("%d",&num[i][j]);
    				dp[i][j]=-1;
    			}
    		}
    		f=l=0;
    		for(int i=1;i<=n;i++){
    			for(int j=1;j<=n;j++){
    				if(dp[i][j]==-1){
    					dfs(i,j);
    					if(f==l){
    						que[l].x=i,que[l].y=j;
    						l++;
    					}
    					else if(dp[i][j]>dp[que[l-1].x][que[l-1].y]||(dp[i][j]==dp[que[l-1].x][que[l-1].y]&&num[i][j]<num[que[l-1].x][que[l-1].y])){
    						l=f;
    						que[l].x=i,que[l].y=j;
    						l++;
    					}
    					else if(dp[i][j]==dp[que[l-1].x][que[l-1].y]&&num[i][j]==num[que[l-1].x][que[l-1].y]){
    						que[l].x=i,que[l].y=j;
    						l++;
    					}
    				}
    			}
    		}
    		printf("%d
    ",dp[que[f].x][que[f].y]);
    		tf=f;f=l;
    		int tx,ty,x,y;
    		while(tf<f){
    			if(f==l){
    				printf("%d
    ",num[que[tf].x][que[tf].y]);
    			}
    			x=que[tf].x; y=que[tf].y;
    			for(int i=0;i<=8;i++){
    				tx=x+dir[i].x;
    				ty=y+dir[i].y;
    				if(ok(tx,ty,x,y)){
    					if(dp[tx][ty]+1==dp[x][y]){
    						if(f==l){
    							que[l].x=tx,que[l].y=ty;
    							l++;
    						}
    						else if(dp[tx][ty]>dp[que[l-1].x][que[l-1].y]||(dp[tx][ty]==dp[que[l-1].x][que[l-1].y]&&num[tx][ty]<num[que[l-1].x][que[l-1].y])){
    							l=f;
    							que[l].x=tx,que[l].y=ty;
    							l++;
    						}
    						else if(dp[tx][ty]==dp[que[l-1].x][que[l-1].y]&&num[tx][ty]==num[que[l-1].x][que[l-1].y]){
    							que[l].x=tx,que[l].y=ty;
    							l++;
    						}
    					}
    				}
    			}
    			tf++;
    			if(tf==f){
    				tf=f; f=l;
    			}
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Visual Source Safe的使用方法
    二十道经典C#面试题
    C#中转义符
    在自己迷惑的时候,提醒自己
    C#中多态
    C#重载和重写
    DataTable定义
    C#怎么调用方法
    mysql数据类型——字符串char(m)和varchar(m)
    mysql数据类型——时间类型
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4297901.html
Copyright © 2020-2023  润新知