加载中...

P7074 [CSP-J2020] 方格取数 题解

题目传送门

题目描述

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


输入格式

第一行有两个整数 n, m

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


输出格式

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


输入输出样例 #1

输入 #1

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

输出 #1

9
 

样例 1 解释

样例1图示


输入输出样例 #2

输入 #2

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

输出 #2

-10
 

样例 2 解释

样例2图示


说明/提示

数据规模与约定

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

2024/2/4 添加一组 hack 数据。


AC代码:

#include<iostream>
 #define int long long
 using namespace std;
 int n,m;
 const int MAXNM = 1024;
 
 int numls[MAXNM][MAXNM];
 int matrix[MAXNM][MAXNM][3];
 //  [x][x][1] = next || up
 //  [x][x][2] = next || down
 //  最后一维表示是从哪里来的
 
 const int INTMIN = -1145141919810;
 int dfs(int x,int y,int from)
 {
 	if (x == n && y == m) return numls[x][y]; 
 	if (x<1 || y<1 || x>n || y>m) return INTMIN;
 	if (matrix[x][y][from] != INTMIN) return matrix[x][y][from];
 	int ans = INTMIN;
 	ans = max( dfs(x, y+1, 1), dfs(x, y+1, 2) );
 	if(from == 1) ans = max( ans, dfs(x+1, y, 1) );
 	else ans = max( ans, dfs(x-1, y, 2) );
 	matrix[x][y][from] = ans + numls[x][y];
 	return matrix[x][y][from];
 }
 void init()
 {
 	for(int i=1;i<=n;i++)
 	{
 		for(int j=1;j<=m;j++)
 		{
 			matrix[i][j][1] = INTMIN;
 			matrix[i][j][2] = INTMIN;
 		}
 	}
 }
 signed main()
 {
 	cin>>n>>m;
 	for(int i=1;i<=n;i++)
 	{
 		for(int j=1;j<=m;j++)
 		{
 			cin>>numls[i][j];
 		}
 	}
 	init();
 	cout<<max(dfs(1,1,1),dfs(1,1,2));
 	return 0;
 }
AC截图:
AC截图

总结:

1、以后注意这种:

matrix[x][y][from] = ans + numls[x][y];
 return matrix[x][y][from];

不要写成了:

matrix[x][y][from] = ans + numls[x][y];
 return ans;

每次这种return,需要想一下返回的是不是最终答案,不然全WA


2、在空间充足的情况下,不管用不用得到,都开long long int