[ SDOI 2016 ] 探险路线
题目
思路
代码
#include <iostream>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
const int N = 810;
int col[N][N], row[N][N], res;
int n, m, w[N][N], v[N][N];
int f[N][N], g[N][N], L[N], R[N], T[N][N];
int uL[N], uR[N], dL[N], dR[N];
void get_cr(int w[][N]) {
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
col[i][j] = col[i - 1][j] + w[i][j],
row[i][j] = row[i][j - 1] + w[i][j];
}
void calc() {
get_cr(v);
for (int i = 1; i <= n; i++)
f[i][1] = v[1][1], g[i][1] = col[i][1];
for (int j = 1; j <= m; j++)
g[1][j] = v[1][1], f[1][j] = row[1][j];
for (int i = 2; i <= n; i++)
for (int j = 2; j <= m; j++)
f[i][j] = max(f[i][j - 1] + v[1][j], max(f[i - 1][j], g[i - 1][j - 1] + row[i][j] + col[i][j] - v[i][j])),
g[i][j] = max(g[i - 1][j] + v[i][1], max(g[i][j - 1], f[i - 1][j - 1] + row[i][j] + col[i][j] - v[i][j]));
memset(L,-0x3f,sizeof(L));memset(R,-0x3f,sizeof(R));
for (int i = 1; i <= n; i++) T[1][i] = row[1][m] - row[1][i];
for (int i = 2; i <= n; i++)
for (int j = 1; j < m; j++)
T[i][j] = max(T[i - 1][j] + v[i][m], row[i][m] + col[i][j + 1] - row[i][j + 1]);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
L[i] = max(L[i], g[i][j]);
for (int i = 1; i <= n; i++)
for (int j = 1; j < m; j++)
R[i] = max(R[i], f[i][j] + T[i][j]);
}
void Solve() {
memcpy(v, w, sizeof v);
calc();
for (int i = 1; i <= n; i++)
uL[i] = L[i], uR[i] = R[i];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
v[i][j] = w[n - i + 1][m - j + 1];
calc();
for (int i = 1; i <= n; i++)
dL[i] = R[n - i + 1], dR[i] = L[n - i + 1];
get_cr(w);
for (int i = 2; i <= n; i++)
uL[i] = max(uL[i], max(uL[i - 1] + w[i][1], uR[i - 1] + row[i][m])),
uR[i] = max(uR[i], max(uR[i - 1] + w[i][m], uL[i - 1] + row[i][m]));
res = max(res, max(uR[n], dL[1]));
for (int i = 1; i <= n - 1; i++)
res = max(res, max(uL[i] + dL[i + 1], uR[i] + dR[i + 1]));
}
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> w[i][j];
Solve();
for (int i = 1; i <= n; i++)
for (int j = i + 1; j <= m; j++)
swap(w[i][j], w[j][i]);
swap(n, m);
Solve();
cout << res << endl;
return 0;
}