原题链接:AcWing 3326. 最大硬币数
题目来源:AcWing 夏季每日一题2023
Mike 有一个 N 行 N 列的方格矩阵。
位于第 i 行第 j 列的方格的位置坐标表示为 (i,j)。
矩阵左上角方格的坐标即为 (1,1)。
每个方格中都包含一定数量的硬币,Mike 只有到达一个方格内时,方可收集方格中的硬币。
Ci,j
表示第 i 行第 j 列的方格中的硬币数量。
当 Mike 处于方格 (i,j) 时,他可以选择移动至方格 (i−1,j−1) 或方格 (i+1,j+1) 中,前提是所选择的方格位于矩阵边界内,且之前没有到达过。
Mike 可以选择从任意方格开始移动,也可以选择在移动至任意方格时结束移动。
Mike 希望尽可能多的收集硬币。
请帮助他确定他可以收集的最大硬币数量。
输入格式
第一行包含整数 T
,表示共有 T
组测试数据。
每组数据第一行包含整数 N
。
接下来 N
行,每行包含 N
个整数,其中第 i 行第 j 列的整数表示 Ci,j
。
输出格式
每组数据输出一个结果,每个结果占一行。
结果表示为 Case #x: y
,其中 x
为组别编号(从 1 开始), y
为可以收集的最大硬币数量。
数据范围
- 60% 的数据满足,1≤T≤100,1≤N≤100。
- 另外 40% 的数据满足,1≤T≤10,1≤N≤1000。
- 100% 的数据满足,0≤
Ci,j
≤107。
输入样例:
2
3
1 2 5
3 6 1
12 2 7
5
0 0 0 0 0
1 1 1 1 0
2 2 2 8 0
1 1 1 0 0
0 0 0 0 0
输出样例:
Case #1: 14
Case #2: 9
样例解释
对于测试数据 1,Mike 可以选择的行进路径为 (1,1)→(2,2)→(3,3),可收集到的最大硬币数量为 14。
对于测试数据 2,Mike 可以选择的行进路径为 (2,3)→(3,4),可收集到的最大硬币数量为 9。
方法一:枚举
思路:
- 本题要求的就是每个左上到右下的斜对角线之和中最大的那一个
- 从1~n开始枚举,每次可以求出两个斜线的和(就是从最左一列出发和从最上一出发),最后sum一下就可以了
- 会爆int,用long long
C++ 代码:
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int t, w[1010][1010];
int main(){
scanf("%d", &t);
for(int cases = 1; cases <= t; cases ++ ){ // cases个询问
int n;
scanf("%d", &n);
// 读入二维数组
for(int i = 1; i <= n; i ++ ){
for(int j = 1; j <= n; j ++ ){
scanf("%d", &w[i][j]);
}
}
ll res = 0;
for(int i = 1; i <= n; i ++ ){
// 从最左边一列开始
ll cnt = 0;
for(int x = i, y = 1; x <= n; x ++ , y ++ )
cnt += w[x][y];
res = max(res, cnt);
// 从最上面一行开始
cnt = 0;
for(int x = 1, y = i; y <= n; x ++ , y ++ )
cnt += w[x][y];
res = max(res, cnt);
}
printf("Case #%d: %lld\n", cases, res);
}
return 0;
}