题意:
在一个二维矩阵上,给出一个起点和终点,矩阵上每个点的值代表价值,求从起点走到终点,再从终点返回起点,能取得的最大价值,且每个点只能走一次
思路:
对于来回路径上取值问题,很容易误以为先算从起点到终点能取得的最大价值,删去走过点后,再算一遍从终点到起点的最大价值
但显然这样只能保证去的时候得到了最大价值,而不能保证全局是最大的,所以不能这么做
将来回路径考虑成同时从起点出发到终点的两条路径,这两条路径的取值和最大,就是来回路能取的最大值
dp[i][j][k][l]表示从起点到(i,j)加上从起点到(k,l)能取得的最大价值
状态转移:dp[i][j][k][l]=max(max(max(dp[i-1][j][k-1][l],dp[i][j-1][k-1][l]),dp[i-1][j][k][l-1]),dp[i][j-1][k][l-1])+a[i][j]+a[k][l];
代码:
#include <iostream>
using namespace std;
const int maxn=55;
int dp[maxn][maxn][maxn][maxn];
int a[maxn][maxn];
int main()
{
int n,m;
cin>>n>>m;
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++){
for(int k=1;k<=n;k++){
for(int l=1;l<=m;l++)
{
if(i+j != k+l) continue;
if(i==k && j==l) continue;
dp[i][j][k][l]=max(max(max(dp[i-1][j][k-1][l],dp[i][j-1][k-1][l]),dp[i-1][j][k][l-1]),dp[i][j-1][k][l-1])+a[i][j]+a[k][l];
}
}
}
}
cout<<max(max(dp[n-1][m][n-1][m],dp[n-1][m][n][m-1]),max(dp[n][m-1][n][m-1],dp[n][m-1][n-1][m]))<<endl;
return 0;
}