wikioi p1169 传纸条

来源:互联网 发布:java培训骗局 编辑:程序博客网 时间:2024/04/27 06:17

传纸条这一题的难度在于两个人的路径不能重复,相信解决了这个问题绝大多数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; }