分析:dp[]数组记录到每个点能行走的最大分数,pre数组记录的是马在上一个点要跳的第几种方案;
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 400;
const int INF = 0x3f3f3f3f;
int dp[maxn][maxn];
int map[maxn][maxn];
int pre[maxn][maxn];
struct node {
int x, y, d;
bool operator<(const node &t) const{
return d > t.d;
}
}e[maxn*maxn];
int dx[] = { 2,-2,1,-1,-1,1,-2,2 };
int dy[] = { 1,-1,2,-2,2,-2,1,-1 };
int n;
int main() {
while (scanf_s("%d", &n) != EOF) {
int cnt = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> map[i][j];
e[cnt].d = map[i][j];
e[cnt].x = i;
e[cnt].y = j;
cnt++;
}
}
sort(e, e + cnt);
int i, j, x, y, tx, ty;
int rx, ry;
int ff = INF;
int ans = -1;
memset(dp, 0, sizeof(dp));
for (int i = 0; i < cnt; i++) {
x = e[i].x;
y = e[i].y;
int ma = -1;
int f = INF;
int t = 0;
for (int j = 0; j < 8; j++) {
tx = x + dx[j];
ty = y + dy[j];
if (tx < 0 || tx >= n || ty < 0 || ty >= n)
continue;
if (t < dp[tx][ty] || (t == dp[tx][ty] && map[tx][ty] < f)) {
t = dp[tx][ty], ma = j, f = map[tx][ty];
}
}
dp[x][y] = ++t;
pre[x][y] = ma;
if (dp[x][y] > ans || (dp[x][y] == ans && map[x][y] < ff)) {
ans = dp[x][y], ff = map[x][y], rx = x, ry = y;
}
}
cout << dp[rx][ry] << endl;
tx = rx, ty = ry;
for (int i = 0; i < dp[rx][ry]; i++) {
cout << map[tx][ty] << endl;
int k = pre[tx][ty];
tx += dx[k];
ty += dy[k];
}
}
return 0;
}