20240330学习总结

1、复习二叉树的相关知识点:

(1)结点的度:结点拥有的子树个数 

树的度:树中各结点中度的最大值

度为0的结点是叶子结点 

(2)树的深度:树当中结点的最大层次

(3)有序树:树中各结点的子树从左至右是有次序的,如果子树变化,会变成另外一个树

无序树:树中结点的各子树无次序

(4)森林:是m各互不相交的树的集合(m>=0)把树的根节点删除就变成了森林,一棵树可以看成一个特殊的森林,给森林中的各子树加上一个双亲结点,森林就会变成子树。树一定是森林,森林不一定是树 。

总结一下,树形结构和线性结构之间有什么区别:

线性结构:第一个数据元素是没有前驱的,最后一个元素是没有后继的,其他数据元素是只有一个前驱只有一个后继的  元素之间的关系是一对一的

树形结构:根节点是只有一个的,是没有双亲的。叶子结点,可以有多个,也是没有孩子的(也就是没有后继),其他结点(也就是中间结点)只有一个双亲但是有多个孩子的   元素之间的关系是一对多的

(5)二叉树的定义:二叉树是有n个结点的有限集合,或者是空集合(也就是一个空树)或者是由一个根节点以及两个不相交的(称为左子树和右子树)的二叉树组成

特点:

每个节点最多有两个孩子(二叉树中不存在度大于2的结点)0 1 2

二叉树的子树有左右之分,次序不能颠倒、

二叉树可以是空集合,根可以有空的左子树或者右子树

3个结点的二叉树可能有几种不同的形态  (根据层次来判断会更快)

暂复习到这里,先看一道题目,关于完全二叉树的,

洛谷:P8681 [蓝桥杯 2019 省 AB] 完全二叉树的权值

现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。

注:根的深度是 11。首先观察完全二叉树,第i层的节点个数应该是2^(i-1),第i层的最后一个节点的序号应该是2^i-1,根据这个性质进行解决,;

#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N];
long long n,maxn,dep=1,sum,ans;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		sum=sum+a[i];
		if(sum>maxn){
			maxn=sum;
			ans=dep;
		}
		dep++;
		sum=0;
	}
	if(sum>maxn){
		maxn=sum;
		ans=dep;
	}
	cout<<ans<<endl;
	return 0;
}

2、复习一个简单的dp问题,杭电的免费馅饼

都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼。说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内。馅饼如果掉在了地上当然就不能吃了,所以gameboy马上卸下身上的背包去接。但由于小径两侧都不能站人,所以他只能在小径上接。由于gameboy平时老呆在房间里玩游戏,虽然在游戏中是个身手敏捷的高手,但在现实中运动神经特别迟钝,每秒种只有在移动不超过一米的范围内接住坠落的馅饼。现在给这条小径如图标上坐标:

为了使问题简化,假设在接下来的一段时间里,馅饼都掉落在0-10这11个位置。开始时gameboy站在5这个位置,因此在第一秒,他只能接到4,5,6这三个位置中其中一个位置上的馅饼。问gameboy最多可能接到多少个馅饼?(假设他的背包可以容纳无穷多个馅饼)

Input

输入数据有多组。每组数据的第一行为以正整数n(0<n<100000),表示有n个馅饼掉在这条小径上。在结下来的n行中,每行有两个整数x,T(0<T<100000),表示在第T秒有一个馅饼掉在x点上。同一秒钟在同一点上可能掉下多个馅饼。n=0时输入结束。

Output

每一组输入数据对应一行输出。输出一个整数m,表示gameboy最多可能接到m个馅饼。
提示:本题的输入数据量比较大,建议用scanf读入,用cin可能会超时。

Sample Input

6
5 1
4 1
6 1
7 2
7 2
8 3
0

Sample Output

4

解决思路:联想到一个三叉树的问题,树塔问题

#include<iostream> 
#include<cstring>
using namespace std;
int n,maxn=-1000,dep;
const int N=100008;
int x[N],y[N],dp[N][20];
int main(){
	while(scanf("%d",&n)!=EOF){
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++){
			scanf("%d %d",&x[i],&y[i]);
			dp[y[i]][x[i]]++;
			dep=max(maxn,y[i]);
		}
		for(int i=dep-1;i>=1;i--){
		    dp[i][0]+=max(dp[i+1][0],dp[i+1][1]);
			for(int j=1;j<10;j++){
				dp[i][j]+=max(max(dp[i+1][j-1],dp[i+1][j]),dp[i+1][j+1]);
			}
			//来处理右边界问题
			dp[i][10]+=max(dp[i+1][10],dp[i+1][9]); 
		}
		cout<<max(max(dp[1][4],dp[1][5]),dp[1][6])<<endl;
	}
	return 0;
}

  • 38
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值