[ SDOI 2016 ] 探险路线

题目

Luogu
LOJ
Acwing

思路

001.png 002.png 003.png

代码


#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;
}
posted @ 2021-07-14 19:32  Protein_lzl  阅读(112)  评论(0编辑  收藏  举报