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\n",dp[que[f].x][que[f].y]);
		tf=f;f=l;
		int tx,ty,x,y;
		while(tf<f){
			if(f==l){
				printf("%d\n",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;
}

  

posted @ 2015-02-23 10:21  chenjunjie1994  阅读(172)  评论(0编辑  收藏  举报