冒险寮
(由于格式问题就不写题目描述了)
【题目分析】
手推了一下,最大费用最大流也是可以的,但这是一道比较明显的棋盘类DP,所以双路DP即可。
因为来回两次,我们就将其视为两个人在走就行了,可以记忆化优化一下。
注意两个人可能走到同一位置,所以要特判一下。
【代码~】
#include<bits/stdc++.h>
using namespace std;
const int MAXN=60;
int dx1[4]={1,1,0,0};
int dx2[4]={0,1,1,0};
int dy1[4]={0,0,1,1};
int dy2[4]={1,0,0,1};
bool used[MAXN][MAXN][MAXN][MAXN];
int f[MAXN][MAXN][MAXN][MAXN];
int ma[MAXN][MAXN];
int m,n,ans;
int dfs(int x1,int y1,int x2,int y2)
{
if(x1==m&&y1==n&&x2==m&&x2==n)
return 0;
if(used[x1][y1][x2][y2])
return f[x1][y1][x2][y2];
used[x1][y1][x2][y2]=1;
int res=0,tmp,nx1,ny1,nx2,ny2;
for(int i=0;i<4;++i)
{
nx1=x1+dx1[i],ny1=y1+dy1[i];
nx2=x2+dx2[i],ny2=y2+dy2[i];
if(nx1>m||ny1>n||nx2>m||ny2>n)
continue;
if((nx1!=m||ny1!=n||nx2!=m||ny2!=n)&&(nx1==nx2&&ny1==ny2))
continue;
tmp=dfs(nx1,ny1,nx2,ny2)+ma[nx1][ny1]+ma[nx2][ny2];
if(tmp>res)
res=tmp;
}
f[x1][y1][x2][y2]=res;
return res;
}
int main()
{
memset(f,0,sizeof(f));
scanf("%d%d",&m,&n);
for(int i=1;i<=m;++i)
for(int j=1;j<=n;++j)
scanf("%d",&ma[i][j]);
ans=dfs(1,1,1,1);
cout<<ans;
return 0;
}