问题描述
蒜国地域是一个 n 行 m 列的矩阵,下标均从 1 开始。蒜国有个美丽的城堡,在坐标 (n,m) 上,蒜头君在坐标 (1,1) 的位置上。蒜头君打算出发去城堡游玩,游玩结束后返回到起点。在出发去城堡的路上,蒜头君只会选择往下或者往右走,而在返回的路上,蒜头君只会选择往上或者往左走,每次只能走一格。已知每个格子上都有一定数量的蒜味可乐,每个格子至多经过一次。
现在蒜头君请你来帮他计算一下,如何计划来回行程,可以收集到最多的蒜味可乐。
输入格式
第一行输入两个整数n,m(1≤n,m≤50),表示蒜国是一个 nn 行 mm 列的矩阵。
接下来输入 n行,每行输入 m 个整数,代表一个 n×m 的矩阵,每个整数代表对应位置上的蒜味可乐数量,每行的每两个整数之间用一个空格隔开。其中蒜头君的位置和城堡的位置上没有蒜味可乐,用 0 表示,其余位置上的整数范围在 [1,100] 内。
输出格式
输出一行,输出一个整数,表示蒜头君在来回路上能收集到的蒜味可乐的最大值。
样例输入
3 3
0 2 9
4 8 6
2 7 0
样例输出
36
#include<bits/stdc++.h>
using namespace std;
int n,m;
int dp[60][60][60][60]={{{{0}}}};
int val[60][60]={{0}};
void solve(){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int s=i+j;
for(int p=1;p<=n;p++){
int q=s-p;
if(q<=0||q>m) continue;
if(i==p&&j==q) continue;
dp[i][j][p][q]=max(max(dp[i-1][j][p-1][q],dp[i-1][j][p][q-1]),max(dp[i][j-1][p][q-1],dp[i][j-1][p-1][q]))+val[i][j]+val[p][q];
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&val[i][j]);
}
}
solve();
cout<<dp[n-1][m][n][m-1]<<endl;
return 0;
}