传纸条这一题的难度在于两个人的路径不能重复,相信解决了这个问题绝大多数OIer都没问题了,当然如果还不行请看看数字三角形吧。
这一题我们可以有一个逆向思维:两个人分别从两个起点a(1,1)->(m,n) b(m,n)->(1,1)
我们也可以假定a也是从(m,n)向(1,1)传递,虽然方向不同,但是不影响路径的大小。
那么我们假定a走的是下行路线。b走的是上行路线。
即a从下面的路径走,b在上面走
那么这里不好画图,但是有4种可能,a在b的右下 左下 左上都是不会和b有路径重合的,只要保证a的坐标始终不在b的右上方即可。
当然一开始的时候我们要做好初始化,(1,1)的起点是允许重合的。
这个单独处理。
这样问题就解决了。
#include<stdio.h>
#include<iostream>
#include<memory.h>
using namespace std;
const int MAX_N = 51;
int M,N;
int G[MAX_N][MAX_N];
int f[MAX_N][MAX_N][MAX_N];
int init()
{
int i,j;
scanf("%d %d",&M,&N);
for (i=1;i<=M;i++)
for (j=1;j<=N;j++)
scanf("%d",&G[i][j]);
memset(f,-1,sizeof(f));
}
bool outs(int a,int b,int c,int d)
{
if (a>M||c>M) return true;
if (b>N||d>N) return true;
if (a<1||c<1) return true;
if (b<1||d<1) return true;
return false;
}
int work(int x1,int y1,int x2,int y2)
{
if (x1==1&&y1==1) return 0;
if (outs(x1,y1,x2,y2)) return 0;
if (x1==x2&&y1>=y2&&!(x1==M&&y1==N)) return 0;
if (f[x1][y1][x2]!=-1) return f[x1][y1][x2];
int tmp=0;
tmp=max(tmp,work(x1,y1-1,x2,y2-1));
tmp=max(tmp,work(x1,y1-1,x2-1,y2));
tmp=max(tmp,work(x1-1,y1,x2,y2-1));
tmp=max(tmp,work(x1-1,y1,x2-1,y2));
return f[x1][y1][x2]=tmp+G[x1][y1]+G[x2][y2];
}
int main()
{
init();
printf("%d",work(M,N,M,N));
return 0;
}