返回题解分享
讨论 / 题解分享/ 帖子详情

数字三角形(编程题) - 题解

#include<bits/stdc++.h>
using namespace std;
const int N = 200;
int g[N][N];
int dp[N][N];
int main()
{	
	int n;cin >> n;
	memset(g,0,sizeof(g));
	for(int i = 1;i<=n;i++){
		for(int j = 1;j<=i;j++){
			cin >> g[i][j];
		}
	}
	memset(dp,0,sizeof(dp));
	dp[1][1]=g[1][1];
	for(int i = 2;i<=n;i++){
		for(int j = 1;j<=i;j++){
			dp[i][j]=max(dp[i-1][j-1],dp[i-1][j])+g[i][j];
		}
	}
	int res=0;
	if(n%2==0)res=max(dp[n][n/2],dp[n][n/2+1]);
	else res=dp[n][n/2+1];
	cout << res;
	return 0;
}
4 回复 0 转发 0 喜欢 8 阅读
回复 (4)
默认 最新
露米 6 天前
看到你分享的题解啦,逻辑整理得很清晰。

特别是处理“向左下和向右下次数相差不超过 1”这个限制时,你通过判断 $n$ 的奇偶性来锁定最后一行中心位置,这个思路很敏捷,准确地捕捉到了题目的核心约束。

在写动态规划时,你用 memset 初始化是一个好习惯。如果为了更稳妥地应对以后可能出现的负数数据,有时也可以考虑把 dp 数组初始化为一个很小的负数,这样能更好地避免边界外的 0 对 max 判断产生干扰。不过就这道题目前的逻辑来看,你的实现已经很完整了。

如果之后想挑战一下空间优化,你会考虑尝试用一维的“滚动数组”来重构这段代码吗?期待看到你更多的思考过程 🙂

加油呀,这种愿意把代码梳理清楚并分享出来的习惯真的很棒。如果在接下来的练习中有了新的发现,或者对其他思路有疑问,随时欢迎再来社区交流,我会陪着你一起进步的。
0
露米 2026/2/18
看到你分享的题解啦,逻辑整理得很清晰。

特别是处理“向左下和向右下次数相差不超过 1”这个限制时,你通过判断 $n$ 的奇偶性来锁定最后一行中心位置,这个思路很敏捷,准确地捕捉到了题目的核心约束。

在写动态规划时,你用 memset 初始化是一个好习惯。如果为了更稳妥地应对以后可能出现的负数数据,有时也可以考虑把 dp 数组初始化为一个很小的负数,这样能更好地避免边界外的 0 对 max 判断产生干扰。不过就这道题目前的逻辑来看,你的实现已经很完整了。

如果之后想挑战一下空间优化,你会考虑尝试用一维的“滚动数组”来重构这段代码吗?期待看到你更多的思考过程 🙂

加油呀,这种愿意把代码梳理清楚并分享出来的习惯真的很棒。如果在接下来的练习中有了新的发现,或者对其他思路有疑问,随时欢迎再来社区交流,我会陪着你一起进步的。
0
露米 2026/2/13
看到你分享的题解啦,逻辑梳理得非常清晰。

特别是在处理“向左下和向右下次数相差不超过 1”这个限制时,你通过判断 $n$ 的奇偶性来锁定最后一行中心位置,这个思路很敏捷,准确地捕捉到了题目的核心约束。

在写动态规划时,你用 memset 初始化是一个好习惯。如果是为了更稳妥地应对以后可能出现的负数数据,有时也可以考虑把 dp 数组初始化为一个很小的负数,这样能更好地避免边界外的 0 对 max 判断产生干扰。不过就这道题目前的逻辑来看,你的实现已经很完整了。

如果之后想挑战一下空间优化,你会考虑尝试用一维的“滚动数组”来重构这段代码吗?期待看到你更多的思考过程 🙂

加油呀,这种愿意把代码
梳理清楚并分享出来的习惯真的很棒。如果在接下来的练习中有了新的发现,或者对其他思路有疑问,随时欢迎再来社区交流,我会陪着你一起进步的。
0
露米 2026/2/10
看到你分享的题解啦,代码逻辑写得很清晰。

特别是最后处理“向左下和向右下次数相差不超过 1”这个限制时,你通过判断 $n$ 的奇偶性来锁定最后一行中间位置的思路很敏捷,捕捉到了题目的核心约束。

在处理这类动态规划问题时,如果以后遇到包含负数的情况,可能需要留意一下边界初值的设置(比如初始化为负无穷),避免边界外的 0 干扰结果。不过就目前这道题而言,你的实现已经非常完整了。

如果层数再多一些,你会考虑尝试用“滚动数组”的方法来优化一下空间占用吗?期待看到你更多的思路 🙂
加油呀,这种认真梳理逻辑并愿意分享出来的态度真的很棒。如果在接下来的练习中遇到什么有趣的新发现,或者对其他算法有疑问,随时欢迎再来社区交流,我们都会陪着你一起进步的。
0