题记
表示现在越来越喜欢 做 孟加拉国的题目了!
要G_G了!
所以说题目是这样的!
题意:
给出一个矩阵,两个人一块从左上角(1,1)位置走到右下角(n,m)位置,求经过的点上的数字之和最大是多少,每一步都只能往最接近右下角的位置走,即下一步的位置可以是(i+1,j)or (i, j+1),如果一个人已经走过了,那么另外一个人就不能够再一次走过去!
such as :
(加黑的数字就是表示 第一个人的路线)
Sample Input
2
3 3
1 1 1
1 0 1
1 1 1
3 4
1 1 0 1
1 1 1 1
0 1 10 1
Sample Output
Case 1: 8
Case 2: 18
思路:
不妨假设 2个人是同时间走的! 那么 只要知道现在2个人的 行号 以及步数,那么他们的列号我们也知道了!
比如:一个人在第 3 行 目前走了 5 步 , 于是就可以知道 他在(3,2) 的位置上
那么一共有 4 种情况 来选择!
(same 表示在不在 一行上!)
1. same down right
2. same right down
3. dif down down
4. dif right right
代码
#include <bits/stdc++.h>
#define N 110
using namespace std;
int T,n,m,a[N][N],dp[3*N][N][N];
int DFS(int step,int linel,int liner)
{
if(dp[step][linel][liner]!=-1)
return dp[step][linel][liner];
int y1=step-(linel-1)+1,y2=step-(liner-1)+1;
dp[step][linel][liner]=0;
if(y1>m || y2>m || linel>n || liner>n) return 0;
dp[step][linel][liner]=max(DFS(step+1,linel+1,liner),DFS(step+1,linel,liner+1));
dp[step][linel][liner]=max(dp[step][linel][liner],max(DFS(step+1,linel+1,liner+1),DFS(step+1,linel,liner)));
if(linel == liner)
dp[step][linel][liner]+=a[linel][y1];
else
dp[step][linel][liner]+=(a[linel][y1]+a[liner][y2]);
return dp[step][linel][liner];
}
int main()
{
scanf("%d",&T);
for(int loc=1; loc<=T; loc++)
{
memset(dp,-1,sizeof(dp));
memset(a,0,sizeof(a));
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
scanf("%d",&a[i][j]);
printf("Case %d: %d\n",loc,DFS(0,1,1));
}
return 0;
}
/*
1. same down right
2. same right down
3. dif down down
4. dif right right
*/