【洛谷】数字三角形(动态规划)

这篇具有很好参考价值的文章主要介绍了【洛谷】数字三角形(动态规划)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

边读边存

优化成一维数组——倒序没用了?


【洛谷】数字三角形(动态规划),题解,数据结构与算法,动态规划,算法

从上往下存,最大值存在最后一行,最后遍历最后一行得到最大值的写法 

边读边存

边读边存,可以有效降低时间复杂度

#include<iostream>
using namespace std;
int dp[1005][1005] = { 0 };
//dp[i][j]表示前面的路径(包括dp[i][j]点本身)能取得的最大值

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
//由于题目数据量较大,上面两行代码可以加速35%左右
	int r, j = 0, cnt = 2, MAX = -1;
	cin >> r;
	cin >> dp[1][1];
//下面的内层循环比较特殊,因为树每往下一层,元素都递增一个
//所以用cnt来记录每层元素的个数
	for (int i = 2; i <= r; ++i)
	{
		while (++j <= cnt)
		{
			cin >> dp[i][j];
			dp[i][j] += max(dp[i - 1][j], dp[i - 1][j - 1]);
//由于是二叉树,因此每个节点只需判断它前面两个结点的值哪个最大即可
//因为是从dp[1][1]开始存入数据,所以i-1和j-1均不会越界
		}
		++cnt;
		j = 0;
	}
	//遍历最后一行判断谁是最大值
	for (int i = 1; i <= r; ++i)
	{
		MAX = max(MAX, dp[r][i]);
	}
	cout << MAX;
	return 0;
}

优化成一维数组——倒序没用了?

在上一篇文章(【洛谷】采药(01背包问题))将二维数组优化成一维数组的过程中,内层循环我们是采用倒序的方式计算dp[ i ][ j ],这是因为如果正序存储dp[ i ][ j ],就会覆盖掉dp[ i-1 ][ j ],这样就无法通过状态方程计算dp[ i ][ j ]。在这道题中同样要避免覆盖掉dp[ i-1 ][ j ],不过为了保证时间复杂度,必须保留边读边存的做法。

接下来尝试一下倒序的方式在这题中是否适用(这么问了肯定不适用,正确答案请移步最后)

int r, j = 3, cnt = 2, MAX = -1;
	cin >> r;
	cin >> dp[1];
	for (int i = 2; i <= r; ++i)
	{
		while (--j >= 1)
		{
			cin >> dp[j];
			dp[j] += max(dp[j], dp[j - 1]);
		}
		++cnt;
		j = cnt;
	}

首先要注意一点,我们是逆序输入,也就是说如果原来输入 3,10,9,那么在数组的里存放的顺序应该是9,10,3(假设单纯的存进去,不进行运算)

那么输入的树应该是镜像的,比如

7

3 8

8 1 0

2 7 4 4

会变成:

         7

      8 3

   0 1 8

4 4 7 2

这两棵树在这道题中其实没有区别,因此不影响。

然后我们输入下面这组数据

4
7
3 8
8 1 0
2 7 4 4

当输入到

4

7

3

时,树的结构如下:

【洛谷】数字三角形(动态规划),题解,数据结构与算法,动态规划,算法 

 接着输入8之后,以下两种情况,你觉得是哪一种?

【洛谷】数字三角形(动态规划),题解,数据结构与算法,动态规划,算法

 是下面的那种。看代码中下面这部分【洛谷】数字三角形(动态规划),题解,数据结构与算法,动态规划,算法

在cin>>dp[1]的时候,已经把dp[1]覆盖成8了,因此公式变成了8+=max(8,0),这样一来答案就错了。不过到这一步,怎么改错也很明显了,既然不想被覆盖,那就引入一个变量来保存一下原本的dp[ j ]就行了嘛。【洛谷】数字三角形(动态规划),题解,数据结构与算法,动态规划,算法

 文章来源地址https://www.toymoban.com/news/detail-597242.html

#include<iostream>
using namespace std;
int dp[1005] = { 0 };

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	int r, j = 3, cnt = 2, MAX = -1, x = 0;
	cin >> r;
	cin >> dp[1];
	for (int i = 2; i <= r; ++i)
	{
		while (--j >= 1)
		{
			cin >> x;
			x += max(dp[j], dp[j - 1]);
			dp[j] = x;
		}
		++cnt;
		j = cnt + 1;
	}
	for (int i = 1; i <= r; ++i)
	{
		MAX = max(MAX, dp[i]);
	}
	cout << MAX;
	return 0;
}

于是空间成功从4MB多降到了800KB

当然,还可以从下往上计算,最后的结果保存在dp[1][1],这样减少了最后遍历整个数组的过程,但是输入的时候没法实现边读边存,最终时间复杂度没有差别。这里引用一下原题下方大神linlin1024的题解

【洛谷】数字三角形(动态规划),题解,数据结构与算法,动态规划,算法

 

到了这里,关于【洛谷】数字三角形(动态规划)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法分析与设计-数字三角形问题(动态规划)(通俗易懂,附源码和图解,含时间复杂度分析)(c++)

    (一)题目 问题描述 给定一个由 n n n 行数字组成的数字三角形,如图所示。 试设计一个算法,计算从三角形的顶至底的一条路径,使该路径经过的数字总和最大。 算法设计 对于给定的由 n n n 行数字组成的数字三角形,计算从该三角形的顶至底的路径经过的数字和的最大值

    2023年04月10日
    浏览(30)
  • 力扣120. 三角形最小路径和(Java 动态规划)

    Problem: 120. 三角形最小路径和 Problem:64. 最小路径和 本题目可以看作是在上述题目的基础上改编而来,具体的思路: 1.记录一个int类型的大小的 n 乘 n n乘n n 乘 n 的数组(其中 n n n 为数组triangle的行数)用于记录 每一个当前阶段的最小路径和 2.大体上可以依据题意得出动态转移

    2024年01月22日
    浏览(29)
  • 蓝桥 卷“兔”来袭编程竞赛专场-03破解三角形密码 题解

    挑战介绍 三角形密码指的是将一串字符串按照正直角三角形的形状排列,传递的信息隐藏在每一行的最后一个字符,然后将所有的行的最后一个字符依次连接,就是需要传递的信息。 例如加密后的字符串是:我们爱的是蓝色的心桥 将加密字符串按照正直角三角形填充后如下

    2023年04月16日
    浏览(28)
  • 【数字三角形】

    题目描述 上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。 路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右 边的那个数。此外,向左下走

    2024年02月05日
    浏览(41)
  • 【数字三角形】(C++版)

    题目描述 上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。 路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右 边的那个数。此外,向左下走

    2024年02月16日
    浏览(26)
  • AcWing 898. 数字三角形 (每日一题)

    像数组下标 出现 i-1 的,在循环的时候从 i=1 开始。 0x3f3f3f3f : 1061109567 Integer.MAX_VALUE : 2147483647 在选用 Integer.MAX_VALUE 时,很可能会出现 数据溢出 。 所以在用 Integer.MAX_VALUE 时 需要先取 MAX 再加 a[i][j]; 注:做 数字三角形 这题时, 初始化时需要注意一下边界 。 由于我们 状态计

    2024年02月11日
    浏览(29)
  • 数字三角形+包子凑数(蓝桥杯JAVA解法)

    题目描述 上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和(路径上的每一步只可沿左斜线向下或右斜线向下走)。 输入描述 输入的第一行包含一个整数 N (1≤N≤

    2024年02月01日
    浏览(28)
  • 蓝桥杯第十一届省赛——数字三角形(python组)

    题目:数字三角形 【问题描述】: 上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最 大的和。 路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右 边

    2023年04月10日
    浏览(35)
  • 湘大 XTU OJ 1148 三角形 题解(非常详细):根据题意朴素模拟+观察样例分析需要计算几轮 具体到一般

    1148 三角形 题目描述 给一个序列, 按下面的方式进行三角形累加,求其和值 。 比如序列为 1,2,3,4,5 输入 有多组样例。每个样例的第一行是一个整数N( 1≤N≤100 ),表示序列的大小, 如果N为0表示输入结束。这个样例不需要处理。 第二行是N个整数,每个整数处于[0,100]之间。

    2024年02月13日
    浏览(33)
  • 【算法挨揍日记】day03——双指针算法_有效三角形的个数、和为s的两个数字

       611. 有效三角形的个数 https://leetcode.cn/problems/valid-triangle-number/ 给定一个包含非负整数的数组  nums  ,返回其中可以组成三角形三条边的三元组个数。 本题是一个关于三角形是否能成立的题目,首先我们假设三角形的三边(a,b,c),我们要保证两边之和大于第三边    题

    2024年02月12日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包