题意
给定一张N*M的图,图中每个点都有权值,一个人开始位于(1,1),目标是(n,m);一个人开始位于(n,1),目标是(1,m),不算两人路径交点的权值,求两人路径权值之和的最大值
要求:两人路径有且只有一个交点
题解
DP的简单变形吧
down_dp1[i][j]:人1从(i,j)出发到达(n,m)的路径和最大值;
up_dp1[i][j]:人1到达(i,j)时路径和的最大值
人2也这样预处理一下就好了
接下来枚举所有可能的交点就好了
智障没有看清题目,只允许有一个交点,WA2了还云里雾里,好在CF有错误数据(其实不知道是好事还是坏事)
既然只可以有一个交点,那么对于该交点,1号人只能从点上面进入,下面出来或者左边进入,右边出来,人2对应地选择路径,这样可以保证有且只有一个交点。
改掉之后没有意识到作为交点不能是第一行,最后一行,第一列,最后一列上的点,WA23
所以枚举只能i:2到n-1;j:2到m-1,终于AC
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3;
int up_dp1[maxn+5][maxn+5];
int down_dp1[maxn+5][maxn+5];
int up_dp2[maxn+5][maxn+5];
int down_dp2[maxn+5][maxn+5];
int mapx[maxn+5][maxn+5];
int main(void)
{
#ifdef ex
freopen ("in.txt","r",stdin);
#endif
int n,m;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i)
{
for (int j=1;j<=m;++j)
{
scanf("%d",&mapx[i][j]);
}
}
//down 从当前位置出发
//up 到达当前位置
for (int i=n;i>=1;--i)
{
for (int j=m;j>=1;--j)
{
down_dp1[i][j]=max(down_dp1[i+1][j],down_dp1[i][j+1])+mapx[i][j];
}
}
for (int i=1;i<=n;++i)
{
for (int j=1;j<=m;++j)
{
up_dp1[i][j]=max(up_dp1[i-1][j],up_dp1[i][j-1])+mapx[i][j];
}
}
for (int i=1;i<=n;++i)
{
for (int j=m;j>=1;--j)
{
down_dp2[i][j]=max(down_dp2[i-1][j],down_dp2[i][j+1])+mapx[i][j];
}
}
for (int i=n;i>=1;--i)
{
for (int j=1;j<=m;++j)
{
up_dp2[i][j]=max(up_dp2[i+1][j],up_dp2[i][j-1])+mapx[i][j];
}
}
int tmax=0;
for (int i=2;i<=n-1;++i)
{
for (int j=2;j<=m-1;++j)
{
//if ((i==1 && j==m) || (i==n && j==m) || (i==1 && j==1) || (i==n && j==1)) continue;
tmax=max(tmax,down_dp1[i][j+1]+up_dp1[i][j-1]+down_dp2[i-1][j]+up_dp2[i+1][j]);
tmax=max(tmax,down_dp1[i+1][j]+up_dp1[i-1][j]+down_dp2[i][j+1]+up_dp2[i][j-1]);
}
}
printf("%d\n",tmax);
}