题目链接
题目大意
给你n*m个方格,每个格子有对应的值
你从(1,1)出发到(n,m)每次只能往下往上往右,走过的点则不能走
求一条路线使得走过的路径的权值和最大
题目思路
如果只是简单的往下和往右走就是直接dp
而如果是可以往上走,那么就要设置dp维度
(dp[i][j][0]代表(i,j)从左转移下来)
(dp[i][j][1]代表(i,j)从上转移下来)
(dp[i][j][2]代表(i,j)从下转移下来)
这个dp显然循环是要从先枚举列,再枚举行
预处理第一列,求答案即可
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=1e3+5;
int n,m;
int a[maxn][maxn];
ll dp[maxn][maxn][3];
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]);
}
}
memset(dp,-0x3f,sizeof(dp));
dp[0][1][1]=0;
for(int i=1;i<=n;i++){
dp[i][1][1]=dp[i-1][1][1]+a[i][1];
}
for(int j=2;j<=m;j++){
for(int i=1;i<=n;i++){
dp[i][j][0]=max({dp[i][j-1][0],dp[i][j-1][1],dp[i][j-1][2]})+a[i][j];
}
for(int i=2;i<=n;i++){
dp[i][j][1]=max({dp[i-1][j][0],dp[i-1][j][1]})+a[i][j];
}
for(int i=n-1;i>=1;i--){
dp[i][j][2]=max({dp[i+1][j][2],dp[i+1][j][0]})+a[i][j];
}
}
printf("%lld
",max(dp[n][m][1],dp[n][m][0]));
return 0;
}