CodeForces 429B——Working out 【DP】

题目传送门

Summer is coming! It’s time for Iahub and Iahubina to work out, as they both want to look hot at the beach. The gym where they go is a matrix a with n lines and m columns. Let number a[i][j] represents the calories burned by performing workout at the cell of gym in the i-th line and the j-th column.

Iahub starts with workout located at line 1 and column 1. He needs to finish with workout a[n][m]. After finishing workout a[i][j], he can go to workout a[i + 1][j] or a[i][j + 1]. Similarly, Iahubina starts with workout a[n][1] and she needs to finish with workout a[1][m]. After finishing workout from cell a[i][j], she goes to either a[i][j + 1] or a[i - 1][j].

There is one additional condition for their training. They have to meet in exactly one cell of gym. At that cell, none of them will work out. They will talk about fast exponentiation (pretty odd small talk) and then both of them will move to the next workout.

If a workout was done by either Iahub or Iahubina, it counts as total gain. Please plan a workout for Iahub and Iahubina such as total gain to be as big as possible. Note, that Iahub and Iahubina can perform workouts with different speed, so the number of cells that they use to reach meet cell may differs.

Input

The first line of the input contains two integers n and m (3 ≤ n, m ≤ 1000). Each of the next n lines contains m integers: j-th number from i-th line denotes element a[i][j] (0 ≤ a[i][j] ≤ 105).

Output

The output contains a single number — the maximum total gain possible.

Examples

input

3 3
100 100 100
100 1 100
100 100 100

output

800

Note

Iahub will choose exercises a[1][1] → a[1][2] → a[2][2] → a[3][2] → a[3][3].
Iahubina will choose exercises a[3][1] → a[2][1] → a[2][2] → a[2][3] → a[1][3].

题意:

一个人从左上走到右下,一个人从左下走到右上,两个人必须有一个点作为见面点,见面点的权值不能拿,问按照规则走,取得最大权值的和为多少。

分析:


首先这是一个和HDU-2084 数塔 很像的一个题,到某个点的最优值用一个简单的dp递推式就可以达到,比如从左上到右下的每个点的最优值可以表示为:dp[i][j] = a[i][j] + max(dp[i-1][j],dp[i][j-1])。由此可以推出其他三个方向的递推式。

题意要求只能由一个交点(虽然我是没看出来,原以为路径可以有多个交点2333

显然,设两人在O点相遇,A只能从1或者2走到O,如果他从1走到O,那他的路线就是1=>O=>3,则B就是4=>O=>2,同理可知,若A是从2走到O,他的路线一定是2=>O=>4,B就是1=>O=>3。

那么最后用n^2的时间枚举每个非边界点作为相遇点的消耗,算出最大值,即是答案。

AC代码

#include <iostream>
#include <vector>
#include <utility>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <cstdio>
#include <set>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long ll;

#define INF 0X3F3F3F

#define MAXN 1005
ll a[MAXN][MAXN];
ll dp1[MAXN][MAXN];
ll dp2[MAXN][MAXN];
ll dp3[MAXN][MAXN];
ll dp4[MAXN][MAXN];


int main() {
	int n, m;
	while (cin >> n >> m) {
		memset(dp1, 0, sizeof(dp1));
		memset(dp2, 0, sizeof(dp2));
		memset(dp3, 0, sizeof(dp3));
		memset(dp4, 0, sizeof(dp4));
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				cin >> a[i][j];
			}
		}


		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				dp1[i][j] = a[i][j] + max(dp1[i - 1][j], dp1[i][j - 1]);
			}
		}
		for (int i = n; i >= 1; i--) {
			for (int j = m; j >= 1; j--) {
				dp2[i][j] = a[i][j] + max(dp2[i + 1][j], dp2[i][j + 1]);
			}
		}
		for (int i = 1; i <= n; i++) {
			for (int j = m; j >= 1; j--) {
				dp3[i][j] = a[i][j] + max(dp3[i - 1][j], dp3[i][j + 1]);
			}
		}
		for (int i = n; i >= 1; i--) {
			for (int j = 1; j <= m; j++) {
				dp4[i][j] = a[i][j] + max(dp4[i][j - 1], dp4[i + 1][j]);
			}
		}

		ll ans = 0;
		for (int i = 2; i < n; i++) {
			for (int j = 2; j < m; j++) {
				ans = max(ans, dp1[i][j - 1] + dp2[i][j + 1] + dp3[i - 1][j] + dp4[i + 1][j]);
				ans = max(ans, dp1[i - 1][j] + dp2[i + 1][j] + dp3[i][j + 1] + dp4[i][j - 1]);
			}
		}
		cout << ans << endl;
	}

	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章