zoukankan      html  css  js  c++  java
  • poj 2111 Millenium Leapcow(记忆化搜索)

    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

    题意:给你一个矩阵,问你按照象棋马的走法,下一步比上一步的数大,问长度最长的序列是多长,然后输出序列。如果有多个最长序列输出字典序最小的那个。
    这是看到的一个代码:
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <queue>
     5 #include <vector>
     6 #include <algorithm>
     7 #include <map>
     8 using namespace std;
     9 typedef pair<int,int>P;
    10 const double eps=1e-9;
    11 const int maxn=200100;
    12 const int mod=1e9+7;
    13 const int INF=1e9;
    14 int M[370][370],dp[370][370];
    15 int N;
    16 int dx[8]= {1,1,2,2,-1,-1,-2,-2};
    17 int dy[8]= {2,-2,1,-1,2,-2,1,-1};
    18 P path[370][370];
    19 vector<P>res;
    20 int DP(int x,int y)
    21 {
    22     int &m=dp[x][y];
    23     if(m) return m;
    24     m=1;
    25     for(int i=0; i<8; i++)
    26     {
    27         int nx=x+dx[i];
    28         int ny=y+dy[i];
    29         if(1<=nx&&nx<=N&&1<=ny&&ny<=N&&M[nx][ny]>M[x][y])
    30         {
    31             if(m<DP(nx,ny)+1)
    32             {
    33                 m=DP(nx,ny)+1;
    34                 path[x][y]=make_pair(nx,ny);
    35             }
    36             else if(DP(nx,ny)+1==m)
    37             {
    38                 if(M[path[x][y].first][path[x][y].second]>M[nx][ny])
    39                 {
    40                     path[x][y]=make_pair(nx,ny);
    41                 }
    42             }
    43         }
    44     }
    45     return m;
    46 }
    47 int main()
    48 {
    49     while(~scanf("%d",&N))
    50     {
    51         for(int i=1; i<=N; i++)
    52         {
    53             for(int j=1; j<=N; j++)
    54             {
    55                 scanf("%d",&M[i][j]);
    56             }
    57         }
    58         int MAX=1,cnt;
    59         for(int i=1; i<=N; i++)
    60         {
    61             for(int j=1; j<=N; j++)
    62             {
    63                 cnt=DP(i,j);
    64                 if(MAX<cnt)
    65                 {
    66                     MAX=cnt;
    67                     res.clear();
    68                     res.push_back(make_pair(i,j));
    69                 }
    70                 else if(MAX==cnt)
    71                 {
    72                     res.push_back(make_pair(i,j));
    73                 }
    74             }
    75         }
    76         int keyx,keyy,key;
    77         key=INF;
    78         for(int i=0; i<res.size(); i++)
    79             if(M[res[i].first][res[i].second]<key)
    80             {
    81                 key=M[res[i].first][res[i].second];
    82                 keyx=res[i].first;
    83                 keyy=res[i].second;
    84             }
    85         printf("%d
    ",MAX);
    86         while(1)
    87         {
    88             printf("%d
    ",M[keyx][keyy]);
    89             int t=path[keyx][keyy].second;
    90             keyx=path[keyx][keyy].first;
    91             keyy=t;
    92             if(!keyx)
    93                 break;
    94         }
    95     }
    96     return 0;
    97 }
    View Code

    知识点:

    这个代码的主要想法是,如同最短路一样,path中储存的是当前节点的下一步应该走的位置,然后进行搜索直到遍历了所有的点。

  • 相关阅读:
    <Graph> Topological + Undirected Graph 310 Union Find 261 + 323 + (hard)305
    <Topological Sort> ( 高频, hard) 269
    <Stack> (高频)394 ( 高频)224
    <DFS & BFS> 286 339 (BFS)364
    <Matrix> 311 378
    <Binary Search> 81 (高频)34 (很难hard, 高频)315 (hard)354
    <LinkedList> 369 (高)143 (第二遍)142 148
    <DP> (高频)139 375 374 (DP hard)312
    <BackTracking> permutation 254 47 60
    <Tree> 298 250 366 199(高频) 98(高频)
  • 原文地址:https://www.cnblogs.com/wang-ya-wei/p/6894790.html
Copyright © 2011-2022 走看看