二刷提高课,题解目录在这里— 提高课的题解目录
从题目意思可以知道一条从左上到右下,一条从右下方到左上,
但是我们变换一下,求的路线最大值,
所以我们选取两条均是左上到右下最大值其实意思是一样的所以思维不要死板!
相比较上题多了一个限制即每个点只能走一次
#include<iostream>
using namespace std;
int w[55][55],f[110][55][55];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>w[i][j];
for(int k=3;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;
int &x=f[k][i1][i2];
if(i1==i2&&j1==j2&&(i1!=n||j1!=m||i2!=n||j2!=m))f[k][i1][i2]=-1e8;
//两点不能重复
else if(j1>=1&&j1<=m&&j2>=1&&j2<=m)
{
x=max(x,f[k-1][i1-1][i2-1]);
x=max(x,f[k-1][i1][i2-1]);
x=max(x,f[k-1][i1][i2]);
x=max(x,f[k-1][i1-1][i2]);
x+=(w[i1][j1]+w[i2][j2]);
}
//此题目要考虑边界问题了上一题目是各自可以走两边
//所以肯定会宁愿就加一边也不会选取界外的零,
//但这里为了使一个格子不走两边将其最小化,
//所以可能出现宁愿选取界外的0,也不选取最小化,导致了出界!
}
cout<<f[n+m][n][n];
return 0;
}