小论树形dp

news2024/12/21 19:36:35

文章目录

  • 树形dp
    • 概述
    • 树形dp + 路径问题
      • 树的最长路径
        • 思路
        • 代码
      • 树的中心
        • 换根DP
        • 思路
        • 代码
      • 数字转换
        • 思路
        • 代码
    • 树形dp + 有依赖的背包
      • 二叉苹果树
        • 思路
        • 代码
    • 树形dp + 状态机
      • 没有上司的舞会
        • 思路
        • 代码
      • 战略游戏
        • 思路
        • 代码
      • 皇宫看守
        • 思路
        • 代码
    • 总结

概述

树形 DP,即在树上进行的 DP。由于树固有的递归性质,树形 DP 一般都是递归进行的。
在树上设计动态规划算法时,一般就以节点从深到浅(子树从小到大)的顺序作为DP的“阶段”,DP的状态表示中,第一维通常是节点编号(代表以该节点为根的子树)。

自底向上dfs,属于树的后序遍历

树形dp + 路径问题

树的最长路径

给定一棵树,树中包含 n 个结点(编号1~n)和 n−1 条无向边,每条边都有一个权值。

现在请你找到树中的一条最长路径。

换句话说,要找到一条路径,使得使得路径两端的点的距离最远。

注意:路径中可以只包含一个点。

输入格式
第一行包含整数 n。

接下来 n−1 行,每行包含三个整数 ai,bi,ci,表示点 ai 和 bi 之间存在一条权值为 ci 的边。

输出格式
输出一个整数,表示树的最长路径的长度。

数据范围
1≤n≤10000,
1≤ai,bi≤n,
−105≤ci≤105
输入样例:
6
5 1 6
1 4 5
6 3 9
2 6 8
6 1 7
输出样例:
22

思路

枚举路径的中间节点
我们先讨论一下,对于给定拓扑结构的树里的任意节点,经过他的路径有哪些:在这里插入图片描述
观察我标出的 红色节点,那么经过他的路径有:
以其 子树中的某个节点 作为 起点,以他作为 终点 的 粉色路径
以其 子树中的某个节点 作为 起点,以 子树中的某个节点 作为 终点 的 蓝色路径
以其 子树中的某个节点 作为 起点,以 非其子树的节点 作为 终点 的 橙色路径
对于第 1 种情况,我们可以直接递归处理其子树,找出到当前子树根节点最长的路径长度即可
对于第 2种情况,我们在处理第 1 种情况时,顺便找出 1类路径的 次长路径
把 最长 和 次长 拼在一起,就是我们要的第 2 种情况
而对于第 3 种情况,我们可以把它归类为其 祖先节点 的第 1,2种情况,让其 祖先节点去处理即可
在这里插入图片描述

代码
N, M = 10010, 10010 * 2
h = [-1] * N
e = [0] * M
w = [0] * M
ne = [-1] * M
idx = 0
d1, d2 = [0] * N, [0] * N
ans = 0

def add(a, b, c) :
	global idx
	e[idx] = b
	w[idx] = c
	ne[idx] = h[a]
	h[a] = idx
	idx += 1

def dfs(u, father) :
	global ans
	i = h[u]
	while i != -1 :
		j = e[i]
		if j != father
			dfs(j, u)
			#最长路径和次长路径的逻辑
			if d1[u] <= d1[j] + w[i] :
				d1[u], d2[u] = d1[j] + w[i], d1[u]
			elif d2[u] < d1[j] + w[i] :
				d2[u] = d1[j] + w[i]
		i = ne[i]
	ans = max(ans, d1[u] + d2[u]) #找到以u为中心的最长路径
	

n = int(input())

for i in range(n - 1) :
	a, b, c = map(int, input().split())
	add(a, b, c), add(b, a, c) #无向边

dfs(1, -1)#任意取一个点为根节点
print(ans)
树的中心

给定一棵树,树中包含 n 个结点(编号1~n)和 n−1 条无向边,每条边都有一个权值。

请你在树中找到一个点,使得该点到树中其他结点的最远距离最近。

输入格式
第一行包含整数 n。

接下来 n−1 行,每行包含三个整数 ai,bi,ci,表示点 ai 和 bi 之间存在一条权值为 ci 的边。

输出格式
输出一个整数,表示所求点到树中其他结点的最远距离。

数据范围
1≤n≤10000,
1≤ai,bi≤n,
1≤ci≤105
输入样例:
5
2 1 1
3 2 1
4 3 1
5 1 1
输出样例:
2

换根DP

此类题目特点是,给定一个树形结构,需要以每个节点为根进行一系列统计。我们一般通过两次扫描来求解此类题目。

  1. 第一次扫描时,任取一个点为根,在“有根树”上执行一次树形DP,也就是在回溯时发生的、自底向上的状态转移。
  2. 第二次扫描时,从刚才选出的根出发,对整棵树执行一次深度优先遍历,在每次递归前进行自顶向下的推导,计算出“换根”后的解。
思路

在确定树的 拓扑结构 后单独求一个节点的 最远距离时,会在该树上去比较哪些路径呢?

  • 从当前节点往下,直到子树中某个节点的最长路径
  • 从当前节点往上走到其父节点,再从其父节点出发且不回到该节点的最长路径
  1. 第一次扫描,任取一个点为根,进行一次树形DP,处理出当前子树对于根的最大距离和次大距离
  2. 第二次扫描,从刚才选出的根出发,对整棵树执行一次深度优先遍历,求解出每个节点的父节点子树到当前节点的最大距离

在这里插入图片描述
如图第二次扫描时,求解父节点的子树到5节点的距离时,需要考虑三种情况,1、父节点的子树到5节点的距离最长,即up[5],2、父节点子树的最长距离到节点5的距离最长,且与节点5最长距离不同路径,3、父节点子树的最长距离到节点5的距离最长,但与节点5最长距离同路径。
我们需要保存每个节点最长距离的子节点的编号

代码
N, M = 10010, 20010
h = [-1] * N
e = [0] * M
w = [0] * M
ne = [-1] * M
idx = 0
d1, d2, s, up= [0] * N, [0] * N, [0] * N, [0] * N

def add(a, b, c) :
	global idx
	e[idx] = b
	w[idx] = c
	ne[idx] = h[a]
	h[a] = idx
	idx += 1
#记录每个节点的最长距离和次长距离,以及最长距离的子节点编号
def dfs_d(u, father) : 
	i = h[u]
	while ~ i :
		j = e[i]
		if j != father :
			dfs_d(j, u)
			if d1[u] <= d1[j] + w[i] :
				d1[u], d2[u], s[u] = d1[j] + w[i], d1[u], j
			elif d2[u] < d1[j] + w[i] :
				d2[u] = d1[j] + w[i]
		i = ne[i]
# 处理每个节点途经父节点的最长距离
def dfs_u(u, father) :
	i = h[u]
	while ~ i :
		j = e[i]
		if j != father :
			if j != s[u] : up[j] = max(up[u], d1[u]) + w[i]
			else : up[j] = max(up[u], d2[u]) + w[i]
			dfs_u(j, u)
		i = ne[i]

n = int(input())

for i in range(n - 1) :
	a, b, c = map(int, input().split())
	add(a, b, c), add(b, a, c)

dfs_d(1, -1) # 任取一个点为根
dfs_u(1, -1) # 从刚才选出的根出发,对整棵树执行一次深度优先遍历

res = 10000010
for i in range(1, n + 1) :
	res = min(res, max(d1[i], up[i]))
	
print(res)
数字转换

如果一个数 x 的约数之和 y(不包括他本身)比他本身小,那么 x 可以变成 y,y 也可以变成 x。

例如,4 可以变为 3,1 可以变为 7。

限定所有数字变换在不超过 n 的正整数范围内进行,求不断进行数字变换且不出现重复数字的最多变换步数。

输入格式
输入一个正整数 n。

输出格式
输出不断进行数字变换且不出现重复数字的最多变换步数。

数据范围
1≤n≤50000
输入样例:
7
输出样例:
3
样例解释
一种方案为:4→3→1→7。

思路

根据题意,单看一个数字 xx,那么他能转换到的数有:

  • x的约数之和 x′(x′<x)
  • 所有大于 x,且约数之和等于 x 的数 xi
    那么我们就能绘出如下抽象图示了:在这里插入图片描述
    由于任意正整数 x,的 约数之和 是 唯一的,且本题要求只有约数之和 小于 自身才能转换
    故对于所有的 x 来说,他向 小于 自己的数转换的边 至多 只有一条,那就是 x的 约数之和 x′(x′<x)
    这样一个图论模型我们就很熟悉了,我们把每一个 数 看作一个 点,把上述这个 转换 看作该点的 入边
    每一个 点,至多只有一条 入边,这就是 森林 呀
    建好图后,本题就 等价于 找出一个森林中,直径最长 的树,并求出该树的直径
代码
N = 50010
h = [-1] * N
e = [0] * N
ne = [-1] * N
idx = 0
cumu = [0] * N
st = [False] * N
ans = 0
d1, d2 = [0] * N, [0] * N

def add(a, b) :
	global idx
	e[idx] = b
	ne[idx] = h[a]
	h[a] = idx
	idx += 1

def dfs(u) : #求最长路径
	global ans
	i = h[u]
	while ~ i :
		j = e[i]
		dfs(j)
		if d1[u] <= d1[j] + 1 :
			d1[u], d2[u] = d1[j] + 1, d1[u]
		elif d2[u] < d1[j] + 1 :
			d2[u] = d1[j] + 1
		i = ne[i]
	ans = max(ans, d1[u] + d2[u])

n = int(input())

# 筛法求约数
for i in range(1, n + 1) : #枚举所有两两相乘的情况,记录其中约数,除去本身
	for j in range(2, n // i + 1) :
		cumu[i * j] += i

for i in range(2, n + 1) : #1没有父节点
	if i > cumu[i] :
		add(cumu[i], i)
		st[i] = True

for i in range(1, n + 1) :
	if not st[i] : #枚举根节点
		dfs(i)

print(ans)

树形dp + 有依赖的背包

二叉苹果树

有一棵二叉苹果树,如果树枝有分叉,一定是分两叉,即没有只有一个儿子的节点。

这棵树共 N 个节点,编号为 1 至 N,树根编号一定为 1。

我们用一根树枝两端连接的节点编号描述一根树枝的位置。

一棵苹果树的树枝太多了,需要剪枝。但是一些树枝上长有苹果,给定需要保留的树枝数量,求最多能留住多少苹果。

这里的保留是指最终与1号点连通。

输入格式
第一行包含两个整数 N 和 Q,分别表示树的节点数以及要保留的树枝数量。

接下来 N−1 行描述树枝信息,每行三个整数,前两个是它连接的节点的编号,第三个数是这根树枝上苹果数量。

输出格式
输出仅一行,表示最多能留住的苹果的数量。

数据范围
1≤Q<N≤100.
N≠1,
每根树枝上苹果不超过 30000 个。

输入样例:
5 2
1 3 1
1 4 10
2 3 20
3 5 20
输出样例:
21

思路

状态表示:
集合:设f[x, t]表示在以x为根的子树中选t个树枝能够保留的苹果数的集合
属性:集合中的苹果数的最大值
状态计算:
设x的子节点集合为Son(x),子节点个数p = ∣ S o n ( x ) ∣ p = |Son(x)|p=∣Son(x)∣。保留x这个节点后,对于x的每个节点y i ∈ S o n ( x ) y_i \in Son(x)yi​∈Son(x),我们可以在以y i y_iyi​根节点的子树上选择保留若干节点(记数量为c i c_ici​),在满足∑ i = 1 p c i = t \sum_{i=1}^pc_i = t∑i=1p​ci​=t
f [ x , t ] = m a x ( ∑ i = 1 p f [ y i , c i ] ) + w [ x , y i ] ,   ( ∑ i = 1 p c i = t ) f[x, t] = max(\sum_{i=1}^pf[y_i, c_i]) + w[x, y _ i], \ ( \sum_{i = 1}^pc_i = t)f[x,t]=max(i=1∑p​f[yi​,ci​])+w[x,yi​], (i=1∑p​ci​=t)
该方程其实是一个分组背包模型。有p = ∣ S o n ( x ) ∣ p = |Son(x)|p=∣Son(x)∣组物品,每组物品都有t个,其中第i组的第j个物品的体积为j,价值为f [ y i , j ] f[y_i, j]f[yi​,j],背包的总体积为t。

代码
N, M = 110, 210
h = [-1] * N
e = [0] * M
ne = [0] * M
w = [0] * M
idx = 0
f = [[0] * N for _ in range(N)]

def add(a, b, c) :
	global idx
	e[idx] = b
	w[idx] = c
	ne[idx] = h[a]
	h[a] = idx
	idx += 1

def dfs(u, father) :
	i = h[u]
	while ~ i : #枚举物品组
		ver = e[i]
		if ver != father :
			dfs(ver, u)
			for j in range(m, -1, -1) : #枚举体积
				for k in range(j) : #枚举物品组中的体积,枚举边数
					f[u][j] = max(f[u][j], f[u][j - k - 1] + f[ver][k] + w[i])
		i = ne[i]

n, m = map(int,input().split())

for i in range(n - 1) :
	a, b, c = map(int, input().split())
	add(a, b, c), add(b, a, c)

dfs(1, -1)
print(f[1][m])

树形dp + 状态机

没有上司的舞会

Ural 大学有 N 名职员,编号为 1∼N。

他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。

每个职员有一个快乐指数,用整数 Hi 给出,其中 1≤i≤N。

现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。

在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。

输入格式
第一行一个整数 N。

接下来 N 行,第 i 行表示 i 号职员的快乐指数 Hi。

接下来 N−1 行,每行输入一对整数 L,K,表示 K 是 L 的直接上司。

输出格式
输出最大的快乐指数。

数据范围
1≤N≤6000,
−128≤Hi≤127
输入样例:
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
输出样例:
5

思路

状态机模型

0:不参加舞会

1:参加舞会

动态规划

状态表示

集合

f[u, 0]:以u做根节点不取u节点的树的最大快乐值

f[u, 1]:以u做根节点取u节点的树的最大快乐值

属性:max

状态计算:以u作根节点的最大快乐值

max(f[u, 0], f[u, 1])

f[u][0] += max

f[j][0],f[j][1],j为u的子节点

f[u][1] +=

f[j][0]

代码
import sys
N = 6010

sys.setrecursionlimit(N)
h = [-1] * N
e = [-1] * N
ne = [-1] * N
idx = 0
happy = [0] * N
has_fa = [False] * N
f = [[0, 0] for _ in range(N)]

def add(a, b) :
	global idx
	e[idx] = b
	ne[idx] = h[a]
	h[a] = idx
	idx += 1

def dfs(u) :
	f[u][1] = happy[u]

	i = h[u]
	while i != -1 :
		j = e[i]
		dfs(j)
		f[u][0] += max(f[j][0], f[j][1])
		f[u][1] += f[j][0]
		i = ne[i]

n = int(input())

for i in range(1, n + 1) :
	happy[i] = int(input())

for i in range(n - 1) :
	a, b = map(int, input().split())
	add(b, a)
	has_fa[a] = True
root = 1
while has_fa[root] :
	root += 1
dfs(root)

print(max(f[root][0], f[root][1]))
战略游戏

鲍勃喜欢玩电脑游戏,特别是战略游戏,但有时他找不到解决问题的方法,这让他很伤心。

现在他有以下问题。

他必须保护一座中世纪城市,这条城市的道路构成了一棵树。

每个节点上的士兵可以观察到所有和这个点相连的边。

他必须在节点上放置最少数量的士兵,以便他们可以观察到所有的边。

你能帮助他吗?

例如,下面的树:

在这里插入图片描述

只需要放置 1 名士兵(在节点 1 处),就可观察到所有的边。

输入格式
输入包含多组测试数据,每组测试数据用以描述一棵树。

对于每组测试数据,第一行包含整数 N,表示树的节点数目。

接下来 N 行,每行按如下方法描述一个节点。

节点编号:(子节点数目) 子节点 子节点 …

节点编号从 0 到 N−1,每个节点的子节点数量均不超过 10,每个边在输入数据中只出现一次。

输出格式
对于每组测试数据,输出一个占据一行的结果,表示最少需要的士兵数。

数据范围
0<N≤1500,
一个测试点所有 N 相加之和不超过 300650。

输入样例:
4
0:(1) 1
1:(2) 2 3
2:(0)
3:(0)
5
3:(3) 1 4 2
1:(1) 0
2:(0)
0:(0)
4:(0)
输出样例:
1
2

思路

状态机模型:

1:放士兵

0:不放士兵

状态表示:
集合:f[x, 0]表示从以x为根的子树中,一部分节点安排士兵,并且x节点不安排士兵的士兵数的集合
f[x, 1]表示从以x为根的子树中,一部分节点安排士兵,并且x节点安排士兵的士兵数的集合
属性:士兵数的最小值
状态计算:
f [ x , 1 ] = ∑ s ∈ S o n ( x ) m i n ( f [ s , 0 ] , f [ s , 1 ] ) + 1 f [ x , 0 ] = ∑ s ∈ S o n ( x ) f [ s , 1 ] f[x, 1] = \sum_{s \in Son(x)} min(f[s, 0], f[s, 1]) + 1\\f[x, 0] = \sum_{s \in Son(x)}f[s, 1]f[x,1]=s∈Son(x)∑​min(f[s,0],f[s,1])+1f[x,0]=s∈Son(x)∑​f[s,1]

代码
import sys
sys.setrecursionlimit(6000)
N = 1510
e = [0] * N
ne = [-1] * N

def add(a, b) :
    global idx
    e[idx] = b
    ne[idx] = h[a]
    h[a] = idx
    idx += 1
    
def dfs(u) :
	f[u][1] = 1
	i = h[u]
	while ~ i :
		j = e[i]
		dfs(j)
		f[u][0] += f[j][1]
		f[u][1] += min(f[j][1], f[j][0])
		i = ne[i]

while True :
    try :
        n = int(input())
    except : break
    h = [-1] * N
    st = [False] * N
    idx = 0
    f = [[0] * 2 for _ in range(N)]
    for _ in range(n) :
        cmd = input().split(':')
        u = int(cmd[0])
        for i in map(int, cmd[1].split(')')[1].split()) :
            add(u, i)
            st[i] = True
    root = 0
    for i in range(n) : 
        if not st[i] :
            root = i
            break
    dfs(root)
    print(min(f[root][0], f[root][1]))
皇宫看守

太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫。

皇宫各个宫殿的分布,呈一棵树的形状,宫殿可视为树中结点,两个宫殿之间如果存在道路直接相连,则该道路视为树中的一条边。

已知,在一个宫殿镇守的守卫不仅能够观察到本宫殿的状况,还能观察到与该宫殿直接存在道路相连的其他宫殿的状况。

大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全天候看守,在不同的宫殿安排看守所需的费用不同。

可是陆小凤手上的经费不足,无论如何也没法在每个宫殿都安置留守侍卫。

帮助陆小凤布置侍卫,在看守全部宫殿的前提下,使得花费的经费最少。

输入格式
输入中数据描述一棵树,描述如下:

第一行 n,表示树中结点的数目。

第二行至第 n+1 行,每行描述每个宫殿结点信息,依次为:该宫殿结点标号 i,在该宫殿安置侍卫所需的经费 k,该结点的子结点数 m,接下来 m 个数,分别是这个结点的 m 个子结点的标号 r1,r2,…,rm。

对于一个 n 个结点的树,结点标号在 1 到 n 之间,且标号不重复。

输出格式
输出一个整数,表示最少的经费。

数据范围
1≤n≤1500
输入样例:
6
1 30 3 2 3 4
2 16 2 5 6
3 5 0
4 4 0
5 11 0
6 5 0
输出样例:
25
样例解释:
在2、3、4结点安排护卫,可以观察到全部宫殿,所需经费最少,为 16 + 5 + 4 = 25。

思路

父节点 放置 哨兵,所有子节点都 可放可不放 哨兵
父节点 不放 哨兵,但是他至少有一个 子节点 放置哨兵,观察住了他
父节点 不放 哨兵,但 父节点 的 父节点 放置哨兵观察,则 子节点 可放可不放 哨兵
状态机模型

  • 被父节点观察 ,不被自己观察(0)
  • 被子节点观察,不被自己观察(1)
  • 被自己来观察 (2)

在这里插入图片描述

代码
import sys
sys.setrecursionlimit(1510)
N = 1510

st = [False] * N
h = [-1] * N
e = [0] * N
ne = [-1] * N
w = [0] * N
idx = 0
f = [[0, 0, 0] for _ in range(N)]

def add(a, b) :
    global idx
    e[idx] = b
    ne[idx] = h[a]
    h[a] = idx
    idx += 1

def dfs(u) :
	f[u][2] = w[u]
	i = h[u]
	while ~ i :
		j = e[i]
		dfs(j)
		#当前节点被父节点看管,并且不被自己看管,则子节点要么被自己看管要么被子节点的子节点看管
		f[u][0] += min(f[j][1], f[j][2])
		#当前节点被自己看管,则子节点可以自己看管也可以被父节点或子节点看管
		f[u][2] += min(f[j][0], f[j][1], f[j][2])
		i = ne[i]
	i = h[u]
	f[u][1] = int(1e9)
	while ~ i :
		j = e[i]
		'''当前节点被子节点看管,且不被自己看管
		枚举被哪个子节点看管,此时当前节点一定被自己看管
		,其余子节点情况是可以被自己看管也可以被子节点的子节点看管,即
		当前节点被父节点看管,并且不被自己看管,减去其中当前节点
		自己看管也可以被子节点的子节点看管的最小值的情况
		'''
		f[u][1] = min(f[u][1], f[j][2] + f[u][0] - min(f[j][1], f[j][2]))
		i = ne[i]

n = int(input())

for _ in range(n) :
    cmd = list(map(int, input().split()))
    ver = cmd[0]
    w[ver], son = cmd[1], cmd[3 : ]
    for i in son :
        add(ver, i)
        st[i] = True
        
root = 0
for i in range(1, n + 1) :
    if not st[i] :
        root = i
dfs(root)
print(min(f[root][1], f[root][2]))

总结

树形dp,好难\doge


//                          _ooOoo_                               //
//                         o8888888o                              //
//                         88" . "88                              //
//                         (| ^_^ |)                              //
//                         O\  =  /O                              //
//                      ____/`---'\____                           //
//                    .'  \\|     |//  `.                         //
//                   /  \\|||  :  |||//  \                        //
//                  /  _||||| -:- |||||-  \                       //
//                  |   | \\\  -  /// |   |                       //
//                  | \_|  ''\---/''  |   |                       //
//                  \  .-\__  `-`  ___/-. /                       //
//                ___`. .'  /--.--\  `. . ___                     //
//              ."" '<  `.___\_<|>_/___.'  >'"".                  //
//            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
//      ========`-.____`-.___\_____/___.-`____.-'========         //
//                           `=---='                              //
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//         佛祖保佑       永无BUG     永不修改                       //

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2185157.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通信工程学习:什么是DQDB分布式队列双总线

DQDB&#xff1a;分布式队列双总线 DQDB&#xff08;Distributed Queue Dual Bus&#xff09;&#xff0c;即分布式队列双总线&#xff0c;是美国电气电子工程师学会(IEEE)802.6标准中定义的一种城域网(MAN)数据链路层通信协议。该协议主要用于城域网的数据、语音和视频传输&am…

Python 中的 os 模块

Python 中的 os 模块 在Python中&#xff0c;os 模块是一个内置的标准库&#xff0c;提供了许多与操作系统交互的功能。它允许你执行一系列操作&#xff0c;如文件和目录操作、环境变量管理等。要在Python脚本中使用os模块&#xff0c;你需要首先导入它。 一些常见的用法&…

如何在 Android 中用 Kotlin 将 dp 转换为 px

我们在开发 Android 应用时&#xff0c;经常需要将 dp&#xff08;密度无关像素&#xff09;转换为 px&#xff08;像素&#xff09;。这是因为不同设备有不同的屏幕密度&#xff0c;使用 dp 可以保持在不同设备上的一致性。&#x1f4f1; 但究竟如何将 dp 转换为 px 呢&#x…

鸿蒙网络管理模块02——Socket

如果你也对鸿蒙开发感兴趣&#xff0c;加入“Harmony自习室”吧&#xff01;扫描下方名片&#xff0c;关注公众号&#xff0c;公众号更新更快&#xff0c;同时也有更多学习资料和技术讨论群。 1、概述 Socket 连接主要是通过 Socket 进行数据传输&#xff0c;支持 TCP/UDP/Mul…

Redis篇(面试题 - 连环16炮)(持续更新迭代)

目录 &#xff08;第一炮&#xff09;一、Redis&#xff1f;常用数据结构&#xff1f; 1. 项目里面到了Redis&#xff0c;为什么选用Redis&#xff1f; 2. Redis 是什么&#xff1f; 3. Redis和关系型数据库的本质区别有哪些&#xff1f; 4. Redis 的线程模型了解吗&#x…

探索未来:掌握python-can库,开启AI通信新纪元

文章目录 **探索未来&#xff1a;掌握python-can库&#xff0c;开启AI通信新纪元**背景介绍**python-can**库简介安装指南函数使用示例应用场景常见问题及解决方案总结 探索未来&#xff1a;掌握python-can库&#xff0c;开启AI通信新纪元 背景介绍 在人工智能和物联网的飞速…

[Go语言快速上手]函数和包

目录 一、Go中的函数 函数声明 多个返回值 可变参数 匿名函数 值传递和地址传递 函数执行顺序&#xff08;init函数&#xff09; 二、Go中的包 基本语法 主要包&#xff08;main package&#xff09; 导入其他包 包的作用域 包的使用 包名别名 小结 一、Go中的函…

重生之我们在ES顶端相遇第 18 章 - Script 使用(进阶)

文章目录 0. 前言1. 基本使用2. 读请求中访问文档字段2.1 遍历 List2.2 判断对象存不存在2.3 判断值是否为空2.4 总结 3. 写请求中访问文档字段3.1 数字相加3.2 字符串相加3.3 将字符串转为数组 0. 前言 在前面部分&#xff0c;我们介绍了 ES 的基本使用和要掌握的基础性读写原…

TypeScript 算法手册【快速排序】

文章目录 1. 快速排序简介1.1 快速排序定义1.2 快速排序特点 2. 快速排序步骤过程拆解2.1 选择基准元素2.2 划分数组2.3 递归排序 3. 快速排序的优化3.1 三数取中法选择基准3.2 插入排序与快速排序结合案例代码和动态图 4. 快速排序的优点5. 快速排序的缺点总结 【 已更新完 Ty…

二分查找算法专题(1)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 目录 二分查找算法的介绍 704. 二分查找 34. 在排序数组中查找元素的第一个和 最后一个位置 35. 搜索插入位置 69. x的平…

10-指针和多维数组

多维数组&#xff0c;本质上是数组的数组&#xff1a; 一、多维数组&#xff1a; int B[2][3] int(*P)[3] B;Print B //400 Print *B; //400 Print B[0] //400 Print &B[0][0] // 400B[i][j] *(B[i]j) *(*(Bi)j); int C[3][2][2] int(*p)[2][2] C; Print C //800 Prin…

大数据开发--1.1大数据概论

目录 一.大数据的概念 什么是大数据&#xff1f; 二. 大数据的特点 三. 大数据应用场景 四. 大数据分析业务步骤 大数据分析的业务流程&#xff1a; 五.大数据职业规划 职业方向 岗位技术要求 六. 大数据学习路线 一.大数据的概念 什么是大数据&#xff1f; 数据 世界…

【北京迅为】《STM32MP157开发板嵌入式开发指南》- 第十六章 Linux 第一个程序 HelloWorld

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

LC记录二:丑数专题,一文秒解丑数3题

文章目录 263.丑数1264.丑数21201.丑数3 263.丑数1 https://leetcode.cn/problems/ugly-number/description/ 简单题&#xff0c;丑数只包含质因子2、3、5。所以直接使用 n 循环 除 2 3 5最后判断结果是否等于1即可。 代码&#xff1a; class Solution {public boolean isUg…

01_SQLite

文章目录 ** SQLite 存储各类和数据类型 **** SQLite 五种亲缘类型** SQLite 创建数据表删除数据表插入数据信息从数据表中获取数据&#xff0c;以结果表的形式返回数据&#xff08;结果集&#xff09;updatedistinctorder bygroup byhaving触发器删除一个触发器&#xff08;tr…

计网问答大题(期末复习)

计网总结笔记 概述 互联网的 2 个重要基本特点&#xff1a;连通性&#xff0c;资源共享 从互联网的工作方式上看&#xff0c;可以划分为两大块&#xff1a; •边缘部分&#xff1a; 由所有连接在互联网上的主机组成&#xff0c;由用户直接使用&#xff0c;用来进行通信&…

并查集【数据结构与算法】【C语言版-笔记】

目录 一、需求分析二、并查集三、代码实现3.1 Find函数3.2 Union函数3.3 优化13.4 终极优化2---压缩策略 一、需求分析 假设有n个互不相交的集合 ◼问题1&#xff1a;给定某个集合中的一个元素&#xff0c;查找该元素属于哪个集合&#xff1f; ◼问题2&#xff1a;如何合并两个…

建筑业挂靠行为的防范建议

在建筑行业中&#xff0c;挂靠行为的普遍存在给许多企业带来了法律风险和信誉风险。为了防范这些风险&#xff0c;企业需要采取一系列有效的措施。 一、加强资质管理 企业应当通过合法途径获取和提升自身的资质等级&#xff0c;避免因资质不足而产生挂靠的需求。加强资质管理是…

【半导体物理基础】第1章 半导体中的电子状态和能带,晶格结构,有效质量

目录 1.1 半导体晶格结构和结合性质 固体的种类 典型晶体 元素半导体 几种晶胞结构 晶向指数与晶面 半导体的晶体结构 金刚石结构 金刚石结构的结晶学原胞 硅、锗相关参数 硅、锗相关参数计算 闪锌矿结构 纤锌矿结构 氯化钠型结构 1.2 半导体中的电子状态和能带…

Study-Oracle-10-ORALCE19C-RAC集群搭建

一路走来,所有遇到的人,帮助过我的、伤害过我的都是朋友,没有一个是敌人。 ORACLE --RAC 搭建理念:准备工作要仔细,每个参数及配置都到仔细核对。环境准备完成后,剩下的就是图像化操作,没啥难度,所以图形化操作偷懒不续写了。 一、硬件信息及配套软件 1、硬件设置 RAC…