PS:伤心,又想不出来,看了大神的题解
AC代码:
![]()
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,f[210][210],a[210][210];
int main()
{
ll i,j,k;
cin>>n>>m;
for (i=1;i<=n;++i)
for (j=1;j<=m;++j)
cin>>a[i][j];
f[1][2]=a[1][2]+a[2][1];//不管怎样都会经过(1,2)和(2,1)先赋初值
//i是当前的点横纵坐标之和
//下面的循环是起码2*3或者3*2棋盘才会进入,如果2*2及以下棋盘已经初定义了
for (i=4;i<n+m;++i)//至于i<n+m我是画草图才理解的
{
for (j=min(i-2,n);j>=1;j--) //滚动数组,i层和i-层有关,所以j,k要一直减小而不是增大,防止数据覆盖
{//j=min(i-2,n)是在不超出的情况下找尽量小的能走的位置
for (k=min(i-1,n);k>j;k--)
{//k在j右边,所以是i-1
if (j>1) //这里的条件判断貌似是不需要的,但加上更好
{
f[j][k]=max(f[j][k],f[j-1][k]);
}
if (j>1&&k>1)
{
f[j][k]=max(f[j][k],f[j-1][k-1]);
}
if (k-1>j)//保证移动前的点没有重合
{
f[j][k]=max(f[j][k],f[j][k-1]);
}
//对于两个都从上边来的,其实是另一对(j,k)的两个都从左边来,所以不用写了
f[j][k]+=a[j][i-j]+a[k][i-k];//把数字带上
}
}
}
cout<<f[n-1][n];//输出左下角左边和上边两个格的数字和就好了
return 0;
}
点击加号展开代码