解题思路
记忆化搜索:
我们设
F
i
,
j
,
0
F_{i,j,0}
Fi,j,0 表示从一个格子上方走到该格子的路径最大和,
F
i
,
j
,
1
F_{i,j,1}
Fi,j,1 表示从一个格子下方走到该格子的路径最大和。如果搜到以前搜过的状态则直接返回搜过的最大和(也就是 F 中的值),否则继续搜索到达该格时的最大和。
PS:CSP日常调换题目顺序。。。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iomanip>
using namespace std;
const long long INF=-1e18;
const int dx[4]={0,1,-1,0};
const int dy[4]={0,0,0,1};
int n,m,a[2000][2000];
long long v[2000][2000][3];
long long dfs(int x,int y,long long w){
if(x<=0||y<=0||x>n||y>m)
return INF;
if(v[x][y][w]!=INF)
return v[x][y][w];
if(w==1)
v[x][y][w]=max(dfs(x-1,y,1),max(dfs(x,y-1,1),dfs(x,y-1,0)))+a[x][y];
else
v[x][y][w]=max(dfs(x+1,y,0),max(dfs(x,y-1,1),dfs(x,y-1,0)))+a[x][y];
return v[x][y][w];
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
v[i][j][1]=v[i][j][0]=INF;
}
v[1][1][1]=v[1][1][0]=a[1][1];
printf("%lld",dfs(n,m,1));
}