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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章