2条路线一起走。
dp[i][j][k][l] 表示 第一个路线走到 i, j 第二个路线走到 k, l;
由于不能重复走, 所以当 2 个路线的点重合 只加一个maps[i][j];
传纸条
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
#define MAXN (50+5)
int maps[MAXN][MAXN], dp[MAXN][MAXN][MAXN][MAXN];
int main()
{
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++)
scanf("%d", &maps[i][j]);
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= m; j ++)
for(int k = 1; k <= n; k ++)
for(int l = 1; l <= m; l ++)
if(i == k && j == l)
dp[i][j][k][l] = max(
max(dp[i-1][j][k-1][j], dp[i-1][j][k][l-1]),
max(dp[i][j-1][k-1][l], dp[i][j-1][k][l-1])) + maps[i][j];
else dp[i][j][k][l] = max(
max(dp[i-1][j][k-1][l], dp[i-1][j][k][l-1]),
max(dp[i][j-1][k-1][l], dp[i][j-1][k][l-1])) + maps[i][j] + maps[k][l];
printf("%d\n", dp[n][m][n][m]);
return 0;
}
方格取数
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define MAXN (10+10)
int maps[MAXN][MAXN];
int dp[MAXN][MAXN][MAXN][MAXN];
int main()
{
int n;
cin >> n;
int a, b, c;
while(scanf("%d%d%d", &a, &b, &c))
{
if(!a && !b && !c) break;
maps[a][b] = c;
}
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
for(int k = 1; k <= n; k ++)
for(int l = 1; l <= n; l ++)
if(i == k && j == l)
dp[i][j][k][l] = max(
max(dp[i-1][j][k-1][j], dp[i-1][j][k][l-1]),
max(dp[i][j-1][k-1][l], dp[i][j-1][k][l-1])) + maps[i][j];
else dp[i][j][k][l] = max(
max(dp[i-1][j][k-1][l], dp[i-1][j][k][l-1]),
max(dp[i][j-1][k-1][l], dp[i][j-1][k][l-1])) + maps[i][j] + maps[k][l];
printf("%d\n", dp[n][n][n][n]);
return 0;
}