题目描述
夏天要到了,小西和小瓜决定去健身。健身房是一个n行m列的矩阵。a[i][j]代表在第i行第j列,可以消耗的卡路里。
小西从第1行第1列出发,要到(n,m);小西可以从a[i][j],走到a[i+1][j],或者a[i][j+1]。
小瓜从(n,1)出发,要到(1,m);小瓜可以从a[i][j]出发,走到a[i-1][j],或者a[i][j+1]。
由于小西和小瓜要聚在一起发张自拍,他们必须在健身房的某一行,某一列相遇。由于他们没有好好健身,所以在自拍地点的卡路里消耗不计入总卡路里消耗值。如果小西和小瓜中任何一个人完成了健身,则健身结束。
你的任务是求出小西和小瓜可以消耗的最大总卡路里值。
我们假设小西和小瓜通过每个格子的速度是相同的,但是他们开始健身的时间不同,所以,到相遇点时各自走过的路程不一定相等,先开始健身的将会先完成。
输入输出格式
输入格式
第一行包含两个整数,n,m(3<=n,m<=1000),代表健身房的行、列数,接下来的i行j列代表a[i][j]((0<=a[i][j]<=10^5),即在第i行,j列可以燃烧的卡路里。
输出格式
输出一个整数:即他们可能消耗的总卡路里的总和的最大值。
输入输出样例
输入样例
3 3
100 100 100
100 1 100
100 100 100
输出样例
800
算法思路
多次简单DP(动态规划)
。
AC代码
#include <iostream>
#include <vector>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
vector<vector<int>> energy(n + 2, vector<int>(m + 2, 0));
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
cin >> energy[i][j];
}
}
// LeftTop To RightBottom, A从(1,1)正向DP到(n,m)
vector<vector<int>> DP_maxEnergy1(n + 2, vector<int>(m + 2, 0));
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
DP_maxEnergy1[i][j] = max(DP_maxEnergy1[i - 1][j], DP_maxEnergy1[i][j - 1]) + energy[i][j];
}
}
// RightBottom To LeftTop, A从(n,m)逆向DP到(1,1)
vector<vector<int>> DP_maxEnergy2(n + 2, vector<int>(m + 2, 0));
for (int i = n; i >= 1; --i)
{
for (int j = m; j >= 1; --j)
{
DP_maxEnergy2[i][j] = max(DP_maxEnergy2[i + 1][j], DP_maxEnergy2[i][j + 1]) + energy[i][j];
}
}
// LeftBottom To RightTop, B从(n,1)正向DP到(1,m)
vector<vector<int>> DP_maxEnergy3(n + 2, vector<int>(m + 2, 0));
for (int i = n; i >= 1; --i)
{
for (int j = 1; j <= m; ++j)
{
DP_maxEnergy3[i][j] = max(DP_maxEnergy3[i + 1][j], DP_maxEnergy3[i][j - 1]) + energy[i][j];
}
}
// RightTop To LeftBottom, B从(1,m)逆向DP到(n,1)
vector<vector<int>> DP_maxEnergy4(n + 2, vector<int>(m + 2, 0));
for (int i = 1; i <= n; ++i)
{
for (int j = m; j >= 1; --j)
{
DP_maxEnergy4[i][j] = max(DP_maxEnergy4[i - 1][j], DP_maxEnergy4[i][j + 1]) + energy[i][j];
}
}
int maxEnergy = 0;
for (int i = 2; i < n; ++i)
{
for (int j = 2; j < m; ++j)
{
maxEnergy = max(maxEnergy, DP_maxEnergy1[i - 1][j] + DP_maxEnergy2[i + 1][j] + DP_maxEnergy3[i][j - 1] + DP_maxEnergy4[i][j + 1]);
maxEnergy = max(maxEnergy, DP_maxEnergy1[i][j - 1] + DP_maxEnergy2[i][j + 1] + DP_maxEnergy3[i + 1][j] + DP_maxEnergy4[i - 1][j]);
}
}
cout << maxEnergy << endl;
return 0;
}