两路dp,两次从(1, 1)走到(n, m),拾取路上的珍珠。
dp[k][i][j] 表示第k步时,一个人在i列,一个人在j列,i + j = k (m + n >= k >= 2)。我一般都会将输入和处理分开来,下面的solve()函数用于处理数据
#include <iostream>
#include <cstdio>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <map>
#include <set>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
#define MAX(a,b,c,d) max(max(a,b),max(c,d))
const int maxn = 200 + 7;
int pic[maxn][maxn];
int dp[maxn << 1][maxn][maxn];
void solve(int n, int m, int pic[][maxn]){
//多路dp
memset(dp, 0, sizeof dp);
for (int k = 2; k <= n + m; k++)
for (int i = 1; i <= n && k - i > 0; i++) //k是两路列数和
for (int j = 1; j <= n && k - j > 0; j++)
dp[k][i][j] =
MAX(dp[k - 1][i][j], //下下
dp[k - 1][i - 1][j - 1], //右右
dp[k - 1][i - 1][j], //右下
dp[k - 1][i][j - 1]) //下右
+ pic[i][k - i] + (i == j ? 0 : pic[j][k - j]);
}
int main()
{
ios::sync_with_stdio(false);
int m, n;//n行,m列
while(cin >> m >> n) {
for (int i = 1; i <=n; ++i) {
for (int j = 1; j <= m; ++j) {
cin >> pic[i][j];
}
}
solve(n, m, pic);
cout << dp[m +n][n][n] << endl;
}
return 0;
}
\
\