思路:
之前遇到过一道题, 问从左上到右下最大是多少,走法是一样的。而这道题是
相当于走两边,那么该怎么走?
如果直接走两遍相同的地方只加一次,那么答案是错的,因为有可能是交叉走。
所以我们选择直接让两个人直接走。dp变成了三维的利用行和列的关系既可。
dp[step][i][j]表示step步第一个人在i行第二个人在j行。
分为两种情况
- i == j 时只能加一次
- i != j 时候可以加两个不同的数字
注意:
循环条件一定要结合step 和 行和列的关系
走到一个位置有四种情况
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 205;
int n,m,a[maxn][maxn];
int dp[maxn*2][maxn][maxn];
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&m,&n);
for(int i = 1;i <= n; i++) {
for(int j = 1;j <= m; j++) {
scanf("%d",&a[i][j]);
}
}
for(int step = 1;step <= n+m; step++) {
for(int i = 1;i <= n && step - i >= 0; i++) {
for(int j = 1;j <= n && step - j >= 0; j++) {
if(i == j) {
dp[step][i][j] = max(dp[step][i][j],dp[step-1][i-1][j-1]+a[i][step-i]);
dp[step][i][j] = max(dp[step][i][j],dp[step-1][i-1][j]+a[i][step-i]);
dp[step][i][j] = max(dp[step][i][j],dp[step-1][i][j-1]+a[i][step-i]);
dp[step][i][j] = max(dp[step][i][j],dp[step-1][i][j]+a[i][step-i]);
}
else {
dp[step][i][j] = max(dp[step][i][j],dp[step-1][i-1][j-1]+a[i][step-i]+a[j][step-j]);
dp[step][i][j] = max(dp[step][i][j],dp[step-1][i-1][j]+a[i][step-i]+a[j][step-j]);
dp[step][i][j] = max(dp[step][i][j],dp[step-1][i][j-1]+a[i][step-i]+a[j][step-j]);
dp[step][i][j] = max(dp[step][i][j],dp[step-1][i][j]+a[i][step-i]+a[j][step-j]);
}
}
}
}
printf("%d\n",dp[m+n][n][n]);
return 0;
}