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.
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.
* 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'.
* 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 }
知识点:
这个代码的主要想法是,如同最短路一样,path中储存的是当前节点的下一步应该走的位置,然后进行搜索直到遍历了所有的点。