同
方格取数
, 状态要写对 f[k][i1][i2]
#include <iostream>
using namespace std;
const int N = 55;
int n,m;
int w[N][N];
int f[N*2][N][N]; // f[k,i1,i2] 表示所有从(1,1),(1,1)分别走到(i1,k-i1),(i2,k-i2)的路径的最大值
// k表示 i+j横纵坐标之和
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>w[i][j];
for(int k=2;k<=n+m;k++)
for(int i1=1;i1<=n;i1++)
for(int i2=1;i2<=n;i2++)
{
int j1=k-i1,j2=k-i2; // k 为 i+j之和
if(j1>=1 && j1<=m && j2>=1 && j2<=m)
{
int t=w[i1][j1];
if(i1 != i2) t += w[i2][j2]; // 走的不是同一格
// int &x = f[k][i1][i2]; // 引用减少代码长度
// //下下
// x=max(x,f[k-1][i1 -1][i2 -1] + t);
// //下右
// x=max(x,f[k-1][i1 -1][i2] + t);
// //右下
// x=max(x,f[k-1][i1][i2 -1] + t);
// //右右
// x=max(x,f[k-1][i1][i2] + t);
for(int a=0;a<=1;a++)
for(int b=0;b<=1;b++)
f[k][i1][i2] = max(f[k][i1][i2],f[k-1][i1-a][i2-b] + t);
}
}
cout<<f[n+m][n][n]; // 此处易写成f[n+n][n][n],需要再来回顾一下状态表示f[k][i1][i2],k=i1 + j1 = i2 + j2
return 0;
}