poj 2111 记忆化搜索

Millenium Leapcow
Time Limit: 2000MS Memory Limit: 30000K
Total Submissions: 2055 Accepted: 773
Case Time Limit: 1000MS

Description

The cows have revised their game of leapcow. They now play in the middle of a huge pasture upon which they have marked a grid that bears a remarkable resemblance to a chessboard of N rows and N columns (3 <= N <= 365).  

Here's how they set up the board for the new leapcow game:  

* First, the cows obtain N x N squares of paper. They write the integers from 1 through N x N, one number on each piece of paper.  

* Second, the 'number cow' places the papers on the N x N squares in an order of her choosing.  

Each of the remaining cows then tries to maximize her score in the game.  

* First, she chooses a starting square and notes its number.  

* Then, she makes a 'knight' move (like the knight on a chess board) to a square with a higher number. If she's particularly strong, she leaps to the that square; otherwise she walks.  

* She continues to make 'knight' moves to higher numbered squares until no more moves are possible.  

Each square visited by the 'knight' earns the competitor a single point. The cow with the most points wins the game.  

Help the cows figure out the best possible way to play the game.

Input

* Line 1: A single integer: the size of the board  

* Lines 2.. ...: These lines contain space-separated integers that tell the contents of the chessboard. The first set of lines (starting at the second line of the input file) represents the first row on the chessboard; the next set of lines represents the next row, and so on. To keep the input lines of reasonable length, when N > 15, a row is broken into successive lines of 15 numbers and a potentially shorter line to finish up a row. Each new row begins on its own line.  

Output

* Line 1: A single integer that is the winning cow's score; call it W.  

* Lines 2..W+1: Output, one per line, the integers that are the starting square, the next square the winning cow visits, and so on through the last square. If a winning cow can choose more than one path, show the path that would be the 'smallest' if the paths were sorted by comparing their respective 'square numbers'.  

Sample Input

4
1 3 2 16
4 10 6 7
8 11 5 12
9 13 14 15

Sample Output

7
2
4
5
9
10
12
13

Source

USACO 2003 U S Open


传送门:点击打开链接


思路:跟普通的记忆化搜索没什么区别,就是在dp数组里面加一个表示下一个点的属性变量,用来输出路径。

/*
 *Li Wenjun
 *Email:1542113545@qq.com
 */
#include<stdio.h>
#include<string.h>
#include<math.h>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <cctype>
#include <stack>
#include <list>
#include <cstdlib>
#include <set>
#include <map>
using namespace std;

#define debug 0
#define MAXN 400
#define INF 0x3f3f3f3f
struct node{
    int ways;
    int i,j;
} dp[MAXN][MAXN];;
int maps[MAXN][MAXN]={0};
int N;
const int dirx[8] ={-2,-1,1,2,1,2,-1,-2};
const int diry[8] ={-1,-2,-2,-1,2,1,2,1};

int bfs(int x,int y)
{
    if(dp[x][y].ways)
        return dp[x][y].ways;

    int maxs=0,x0,y0;
    int maxx=N,maxy=N;
    for(int i=0;i<8;i++)
    {
        x0=x+dirx[i];
        y0=y+diry[i];
        if(x0>=0 && y0>=0 &&x0<N && y0<N && maps[x0][y0]>maps[x][y])
        {
            if(maxs<bfs(x0,y0)||(maxs==bfs(x0,y0)&&maps[x0][y0]<maps[maxx][maxy]))
            {
                maxs = bfs(x0,y0);
                maxx = x0;
                maxy = y0;
            }
        }
    }
    dp[x][y].ways = maxs+1;
    if(maxs >0 )
     {
         dp[x][y].i=maxx;
         dp[x][y].j=maxy;
     }
     return dp[x][y].ways;
}

int main()
{
    #if debug
    freopen("in.txt", "r", stdin);
    #endif //debug
     cin.tie(0);
     cin.sync_with_stdio(false);

    while(cin >> N)
    {
        maps[N][N]=INF;
        for(int i=0;i<N;i++)
            for(int j=0;j<N;j++)
            {
                cin >> maps[i][j];
                dp[i][j].ways = 0;
                dp[i][j].i=-1;
                dp[i][j].j=-1;
            }
        int maxi,maxj,maxs=0;
        for(int i=0;i<N;i++)
            for(int j=0;j<N;j++)
        {
            bfs(i,j);
            if(maxs<dp[i][j].ways || (maxs==dp[i][j].ways&&maps[i][j]<maps[maxi][maxj]))
            {
                maxs=dp[i][j].ways;
                maxi=i;
                maxj=j;
            }
        }
        cout << maxs << endl;
        int a,b;
        while(maxi!=-1)
        {
            cout << maps[maxi][maxj] << endl;
            a = maxi; b = maxj;
            maxi = dp[a][b].i;
            maxj = dp[a][b].j;
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值