[CSP-J2020] 方格取数

题目描述

设有 n \times mn×m 的方格图,每个方格中都有一个整数。现有一只小熊,想从图的左上角走到右下角,每一步只能向上、向下或向右走一格,并且不能重复经过已经走过的方格,也不能走出边界。小熊会取走所有经过的方格中的整数,求它能取到的整数之和的最大值。

输入格式

第一行有两个整数 n, mn,m。

接下来 nn 行每行 mm 个整数,依次代表每个方格中的整数。

输出格式

一个整数,表示小熊能取到的整数之和的最大值。

样例 #1

样例输入 #1

3 4
1 -1 3 2
2 -1 4 -1
-2 2 -3 -1

Copy

样例输出 #1

9

Copy

样例 #2

样例输入 #2

2 5
-1 -1 -3 -2 -7
-2 -1 -4 -1 -2

Copy

样例输出 #2

-10

Copy

提示

样例 1 解释

样例 2 解释

数据规模与约定

  • 对于 20\%20% 的数据,n, m \le 5n,m≤5。
  • 对于 40\%40% 的数据,n, m \le 50n,m≤50。
  • 对于 70\%70% 的数据,n, m \le 300n,m≤300。
  • 对于 100\%100% 的数据,1 \le n,m \le 10^31≤n,m≤103。方格中整数的绝对值不超过 10^4104。

 思路

首先,可以先定义一个三位数组at[i][j][k],i,j为位置,k为上一步方向。

这样就可以得出公式:

j>1:

at[i][j][0]=maxx(at[i][j-1][1],maxx(at[i][j-1][0],at[i][j-1][2]))+aa[i][j];

i>1:
at[i][j][1]=maxx(at[i-1][j][0],at[i-1][j][1])+aa[i][j]; 
i<n:
at[i][j][2]=maxx(at[i+1][j][0],at[i+1][j][2])+aa[i][j]; 

代码见下:

#include<bits/stdc++.h>
using namespace std;
long long iom[1024][1024],n,m,x,a,aa[2024][2024],at[2001][2001][5],dd0=-10,aaa=-1e17+1;
long long maxx(long long a,long long b){
	// return a>b;
	if(a<=b) return b;
	else return a;
}
int main(){
	cin>>n>>m;
	memset(at,-63,sizeof(at));
	for(long long i=1;i<=n;i++){
		for(long long j=1;j<=m;j++){
			cin>>aa[i][j];
			at[i][j][0]=aaa;
			at[i][j][1]=aaa;
			at[i][j][2]=aaa;
		}
	}	
	at[1][1][0]=aa[1][1];
	at[1][1][1]=aa[1][1];
	at[1][1][2]=aa[1][1];
	for(long long i=2;i<=n;i++){
		at[i][1][1]=at[i-1][1][1]+aa[i][1];		
	}
	for(long long j=1;j<=m;j++){	
		for(long long i=1;i<=n;i++){
			if(j!=1) at[i][j][0]=maxx(at[i][j-1][1],maxx(at[i][j-1][0],at[i][j-1][2]))+aa[i][j];
			if(i>=2){
				at[i][j][1]=maxx(at[i-1][j][0],at[i-1][j][1])+aa[i][j];	
			}						
		}
		for(long long i=n-1;i>=1;i--){
			at[i][j][2]=maxx(at[i+1][j][0],at[i+1][j][2])+aa[i][j];			
		}
	}	
	cout<<maxx(at[n][m][1],maxx(at[n][m][0],at[n][m][2]));
}

 

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值