挺好的一个题目,要注意解题时满足一个性质, 即若一个格子选了往左, 则该格子左侧的格子都往左, 同理一个格子若选择了往上, 所有上面的格子都选择往上
想来想去, 采用递推似乎不好进行, 这里用记忆化搜索
#include <cstdio>
#include <algorithm>
using namespace std;
int ura[510][510], rad[510][510];
int row[510][510], col[510][510];
int dp[510][510];
int n, m;
void init()
{
for(int i=1; i<=n; i++)
row[i][1] = ura[i][1];
for(int i=1; i<=n; i++)
for(int j=2; j<=m; j++)
row[i][j] = row[i][j-1] + ura[i][j];
for(int i=1; i<=m; i++)
col[i][1] = rad[1][i];
for(int i=1; i<=m; i++)
for(int j=2; j<=n; j++)
col[i][j] = col[i][j-1] + rad[j][i];
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
dp[i][j] = -1;
}
int find(int i, int j)
{
if(dp[i][j] > 0)
return dp[i][j];
if(i==1 && j==1)
return dp[i][j] = max(rad[i][j], ura[i][j]);
if(i == 1)
return dp[i][j] = max(row[i][j], find(i, j-1)+rad[i][j]);
if(j == 1)
return dp[i][j] = max(col[1][i], find(i-1, j)+ura[i][j]);
return dp[i][j] = max(find(i-1, j)+row[i][j], find(i, j-1)+col[j][i]);
}
int main()
{
int t, ca = 1;
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &n, &m);
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
scanf("%d", &ura[i][j]);
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
scanf("%d", &rad[i][j]);
init();
printf("Case %d: %d\n", ca++, find(n, m));
}
return 0;
}