题目意思:
给n*m的矩阵,每个格子有个数,A从(1,1)出发只能向下或右走,终点为(n,m),B从(n,1)出发只能向上或右走,终点为(1,m)。两个人的速度不一样,走到的格子可以获的该格子的数,两人相遇的格子上的数两个人都不能拿。求A和B能拿到的数的总和的最大值。
#include<iostream>
#include<string.h>
#define maxest 1e6
using namespace std;
int dp1[1005][1005], dp2[1005][1005], dp3[1005][1005], dp4[1005][1005], a[1005][1005];
int main()
{
long long sum=0,r;
int n,i,j,h,m;
r=-maxest;
memset(a,0,sizeof(a));
cin>>n>>m;
for(i=1; i<=n; ++i)
{
for(j=1; j<=m; ++j)
cin>>a[i][j];
}
memset(dp1,0,sizeof(dp1));
memset(dp2,0,sizeof(dp2));
memset(dp3,0,sizeof(dp3));
memset(dp4,0,sizeof(dp4));
for(i=n; i>=1; --i)
{
for(j=m; j>=1; --j)
dp1[i][j]=max(dp1[i+1][j],dp1[i][j+1])+a[i][j];// you xia
}
for(i=1; i<=n; ++i)
{
for(j=1; j<=m; ++j)
dp2[i][j]=max(dp2[i-1][j],dp2[i][j-1])+a[i][j];// zuoshang
}
for(i=1; i<=n; ++i)
{
for(j=m; j>=1; --j)
dp3[i][j]=max(dp3[i-1][j],dp3[i][j+1])+a[i][j];// you shang
}
for(i=n; i>=1; --i)
{
for(j=1; j<=m; ++j)
dp4[i][j]=max(dp4[i+1][j],dp4[i][j-1])+a[i][j];// zuoxia
}
for(i=1; i<=n; ++i)//1 通过 2 不通过 原因:重合个数只能为一个 所以 一个向左一个向下 一个向右 一个向下
{
for(j=1; j<=m; ++j)
{
if(i==1||j==1||i==n||j==m)continue;//如果不加入此语句会引入奇怪的路径比如dp[0][1] 防止越界 之所以不用考虑边界点的相遇是因为无法保证相遇点只有一个
sum=0;
sum+=dp1[i][j+1];//youxia
sum+=dp2[i][j-1];//zuoshang
sum+=dp3[i-1][j];//youshang
sum+=dp4[i+1][j];//zuoxia
// sum-=4*a[i][j];
if(sum>=r)
r=sum;
sum=0;
sum+=dp1[i+1][j];
sum+=dp2[i-1][j];
sum+=dp3[i][j+1];
sum+=dp4[i][j-1];
if(sum>=r)
r=sum;
}
}
cout<<r;
return 0;
}
n,m<=1000
解题思路:
dp.
先预处理出每个格子到四个角落格子的路径最大数值,然后枚举两个人相遇的交点格子,枚举A、B的进来和出去方式(一定注意),求最大值即可,不能存在橡胶在边界情况。
注意边界情况。
不得不说cf的样例质量真是高