2020CSP第二轮 方格取数(number)

题目描述

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

输入

输入文件名为 number.in。
第 1 行两个正整数 𝑛, 𝑚。
接下来 𝑛 行每行 𝑚 个整数,依次代表每个方格中的整数。

输出

输入文件名为 number.out。
一个整数,表示小熊能取到的整数之和的最大值。

样例输入

【样例 1 输入】

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

【样例 2 输入】

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

样例输出

【样例 1 输出】

9

【样例 2 输出】

-10 

数据范围限制

对于 20% 的数据,𝑛, 𝑚 ≤ 5。
对于 40% 的数据,𝑛, 𝑚 ≤ 50。
对于 70% 的数据,𝑛, 𝑚 ≤ 300。
对于 100% 的数据,1 ≤ 𝑛, 𝑚 ≤ 1000。方格中整数的绝对值不超过 104

解题:

题目大意:

给出一个 n × m n×m n×m的矩阵,每个格子有个权值,求从左上角到右下角的在大权值和(可以往右,上,下走)。

思路:

这道题用肉眼看都是用DP,但正常的DP做这道题不能向上走,所以我们考虑分类讨论:
从左边来的(i,j)的最大权值和为lefti,j
从上边来的(i,j)的最大权值和为upi,j
从下边来的(i,j)的最大权值和为downi,j
然而DP式显而易见:

  1. left可以从left,up,down更新;
  2. up可以从left,up更新;
  3. down可以从left,down更新;

更新的过程就和普通DP一样,注意顺序。

代码:

#include<cstdio>
#define Fu(i,a,b) for(int i=(a);i<=(b);i++)
#define Fd(i,a,b) for(int i=(a);i>=(b);i--)
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define INF 11999999999
long long n,m,a[1005][1005],up[1005][1005],down[1005][1005],left[1005][1005];//不开long long见祖宗
long long max(long long x,long long y){
	if(x>y)return x;
	return y;
}
int main(){
	fre(number);
	scanf("%lld%lld",&n,&m);
	Fu(i,1,n)Fu(j,1,m){
		scanf("%lld",&a[i][j]);
		up[i][j]=down[i][j]=left[i][j]=-INF;
	}
	up[1][1]=down[1][1]=left[1][1]=a[1][1];
	Fu(j,1,m){
		Fu(i,1,n){//先转移up和left
			if(i!=1) up[i][j]=max(up[i-1][j],left[i-1][j])+a[i][j];
			if(j!=1) left[i][j]=max(left[i][j-1],max(up[i][j-1],down[i][j-1]))+a[i][j];
		}
		Fd(i,n-1,1)down[i][j]=max(down[i+1][j],left[i+1][j])+a[i][j];
	}
	printf("%lld",max(up[n][m],left[n][m]));
	fclose(stdin);
	fclose(stdout);
	return 0;
}
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值