【2018/07/12测试T2】【SDOJ 3518】抢匪的财宝

【题目】

问题描述:

古威市长和韩丁纳市长都争着要找到抢匪野蛮老危的地图宝藏,放在自己城市的展览馆里。汪汪队帮助古威市长抢先一步找到了藏宝藏的地方。

宝藏埋在洞穴中长为n, 宽为m的矩形地面下。汪汪队从洞穴入口A(图中左上角)进入,从洞穴出口B(图中右下角)离开,每步只能向下走或向右走,当走到[x,y]方格时,可取出[x,y]方格及与[x,y]相邻的上下左右四个方向方格中的全部财宝。每个方格中的数表示财宝数量,如下图所示:

【2018/07/12测试T2】【SDOJ 3518】抢匪的财宝_第1张图片

 

汪汪队从图中A[1,1]走到B[5,5]格时:

通过的路径是[1,1]→[2,1]→[3,1]→[4,1]→[4,2]→[4,3]→[4,4]→[4,5]→[5,5]

最多能取到财宝的数量为:0+1+2+1+0+3+0+0+8+5+0+5+0+6+7+0+8+8+6=60

输入格式:

输入文件treasure.in中有n+1行。

第1行包含2个用空格分开的正整数n、m,分别表示洞穴中埋藏财宝地面的长和宽;

接下来的n行,每行m个用空格分隔的正整数,表示各个格子中的财宝数量。

输出格式:

输出文件treasure.out中有1个正整数,是汪汪队最多能取到的财宝数量。

样例数据:

输入

5 5

0 1 2 0 5

2 1 3 0 0

0 3 6 8 6

0 0 5 5 7

8 0 0 0 8

输出

60

备注:

数据规模与约定:

100%的数据:1≤n,m≤500。

 

【分析】

emmm……,暴力大法好

这是一道动态规划的题,但我是用深搜做的(因此只有30分)

我们用f[i][j][0]表示从上边转移来的答案用f[i][j][1]表示从左边转移来的答案,那么:

f[i][j][0]=max(f[i-1][j][0]+a[i+1][j]+a[i][j+1]+a[i][j-1],f[i-1][j][1]+a[i+1][j]+a[i][j+1]);

f[i][j][1]=max(f[i][j-1][1]+a[i+1][j]+a[i][j+1]+a[i-1][j],f[i][j-1][0]+a[i+1][j]+a[i][j+1]);

(具体可以自己推一推,还是很好理解的)

 

【代码】

#include
#include
#include
using namespace std;
const int N=505;
int a[N][N],f[N][N][2];
int main()
{
//	freopen("treasure.in","r",stdin);
//	freopen("treasure.out","w",stdout);
	int n,m,i,j,ans;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;++i)
	  for(j=1;j<=m;++j)
	    scanf("%d",&a[i][j]);
	for(i=1;i<=n;++i)  f[i][0][0]=a[i][1];
	for(j=1;j<=m;++j)  f[0][i][1]=a[1][j];
	for(i=1;i<=n;++i)
	{
		for(j=1;j<=m;++j)
		{
			f[i][j][0]=max(f[i-1][j][0]+a[i+1][j]+a[i][j+1]+a[i][j-1],f[i-1][j][1]+a[i+1][j]+a[i][j+1]);
			f[i][j][1]=max(f[i][j-1][1]+a[i+1][j]+a[i][j+1]+a[i-1][j],f[i][j-1][0]+a[i+1][j]+a[i][j+1]);
		}
	}
	ans=max(f[n][m][0],f[n][m][1]);
	printf("%d",ans);
//	fclose(stdin);
//	fclose(stdout);
	return 0;
}

你可能感兴趣的:(#,线性DP)