树上背包学习笔记
树上背包,顾名思义,就是在树上跑背包。每日顾名思义
Q:那么到底为什么要树上跑背包 dp 呢?
A:因为我们到现在学的背包 dp 还是属于较浅的一类,什么 01 背包、完全背包还是多重背包,但是如果这个东西变得较为复杂一些,例如如果存在了依赖关系(即选某个东西才可以选另一个东西),前面的背包就束手无策了。
实际上,树上背包就是把背包 dp 用到了树的上面。
不如先看一个引入题。
P2014 [CTSC1997] 选课
在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习。现在有 N N N 门功课,每门课有个学分,每门课有一门或没有直接先修课(若课程 a 是课程 b 的先修课即只有学完了课程 a,才能学习课程 b)。一个学生要从这些课程里选择 M M M 门课程学习,问他能获得的最大学分是多少?
N , M ≤ 300 N,M \le300 N,M≤300。
发现每一个东西都可能存在一个依赖关系,果断使用树上背包。
注意到题面中有这样的一句话:
每门课有一门或没有直接先修课
联想到树上面去,发现每门课如果有一门先修课,就类似于每一个儿子都恰好有一个父亲。每门课如果没有先修课,就类似于每一个根结点。
于是考虑根据先修课的关系来建图,最终会形成一个森林的形式,每一棵树之间互不干扰。
但是这样的话,又会产生问题:最终是所有的点中选择 M M M 个,而不是单棵树中选择 M M M 个。
所以要将森林重新变成一颗更大的树。考虑建 0 0 0 号虚点,作为新的树的根结点,并连接原本每一棵树的根结点作为儿子。
但是这时候有一个小细节:因为 0 0 0 是必选的(否则其他东西都选不了),所以直接将 m + 1 → m m+1 \to m m+1→m 即可。
于是我们成功地将问题转化成了:
给定一棵树,点带权,需要你在里面选 M M M 个点,注意如果要选儿子就必须要选父亲。求最终权值。特别地, 0 0 0 的权值为 0 0 0。
考虑 d p dp dp。设 d p u , i dp_{u,i} dpu,i 表示在 u u u 为根的子树内,选 i i i 个可以得到的最大权值是多少。
考虑转移,但是好像遇到了亿点点麻烦。。。显然可以枚举每一个子结点的子树选了多少个,最终合并起来得到答案,但是太慢了。
所以,这样的状态并不能行得通。因此,考虑改变状态。
注意我们讲的是树上背包,但是我们只是在树上跑了 dp,并没有跑背包。所以考虑背包。
显然可以把点权变成价值,而把 1 1 1 作为每一个点的代价,而每一个点可以选择也可以不选择。这样就转换为了一个背包问题。
考虑使用 d p u , i , j dp_{u,i,j} dpu,i,j 表示 u u u 为根的子树内,考虑了前 i i i 个子结点,选了 j j j 个可以得到的最大权值是多少。
转移显然。为了优化转移方程,可以使用滚动数组。因为这是 01 背包所以需要倒序处理。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define N 310
int n, m, x, y, dp[N][N], val[N];
vector<int> edge[N];void dfs(int u) {dp[u][1] = val[u];for (auto v : edge[u]) {dfs(v);for (int i = m; i >= 1; i--)//转移 u 选了 i 节课的答案for (int j = i - 1; j >= 1; j--)//u 的这个儿子 v 选了 i - j 节课的答案dp[u][i] = max(dp[u][i], dp[u][i - j] + dp[v][j]);//合并两个背包}
}signed main() {ios::sync_with_stdio(0);cin >> n >> m;m++;for (int x = 1; x <= n; ++x) {cin >> y >> val[x];edge[y].push_back(x);}dfs(0);cout << dp[0][m] << endl;return 0;
}
这里的复杂度是 O ( n × m 2 ) O(n \times m^2) O(n×m2) 的,有一些慢,后面我们会讲更加快速的做法。
观察 dfs 里面的转移步骤,可以发现这个东西本身其实上可以说是把子结点的背包合并了。这个观点很好理解。所以,这种求解树上背包的方法也叫做dfs 合并。
所以这个有依赖的背包就这么做完了,但是以后的树上背包大差不差的都是一个样子,所以就可以按照固定的东西想即可。
P2014 更好的写法
实际上这里还有一种实现方法,那就是使用 s u m sum sum 来把转移次数优化一下,尤其是 n , m n,m n,m 同阶的时候。
到底是怎么思考的呢?
很容易发现,上面的代码有一行是 for (int i = m; i >= 1; i--)
,但是实际上我们并不需要枚举那么多次,实际上只需要枚举 s u m sum sum 次就可以了。(当然如果 min ( m , s u m ) \min(m,sum) min(m,sum) 还可以更快)
所以把 for (int i = m; i >= 1; i--)
更改成 for(int i = min(m, sum[u]);i >= 0;i--)
即可。
考虑同样把这个东西用到 for (int j = i - 1; j >= 1; j--)
上面去。但是这样子是做差的,所以考虑枚举 v
选了多少课,以代替以前的枚举。
于是:
for (int j = i - 1; j >= 1; j--)dp[u][i] = max(dp[u][i], dp[u][i - j] + dp[v][j]);
变成了:
for(int j = min(m, sum[v]);j >= 0;--j)dp[u][i + j] = max(dp[u][i + j], dp[u][i] + dp[v][j]);//把减变成了加
最终得出来这样的代码:
void dfs(int u,int pre)
{/* DP初始化 */ sum[u] = 1;for(auto v : edge[u]) if(v != pre) {dfs(v,u);for(int i = min(m, sum[u]);i >= 0;--i)//枚举 u 选了 i 节课for(int j = min(m, sum[v]);j >= 0;--j) //枚举 v 选了 j 节课dp[u][i + j] = max(dp[u][i + j], dp[u][i] + dp[v][j]);sum[u] += sum[v];}
}
略加数学分析可得这样的代码复杂度是 O ( n 2 ) O(n^2) O(n2)。
是这样分析的:对于每一个 u u u 都最多要转移 s u m u × n sum_u \times n sumu×n 次,而把所有结点加起来就是 ∑ ( s u m u × n ) = ∑ s u m u × n = n × n \sum (sum_u \times n) = \sum sum_u \times n = n \times n ∑(sumu×n)=∑sumu×n=n×n,是不是很奇妙!
当然,如果 m m m 远小于 n n n,则使用 O ( n × m 2 ) O(n \times m^2) O(n×m2) 会优秀一点,否则使用 O ( n 2 ) O(n^2) O(n2) 优秀一点,这两个东西都不可以抛弃掉。
U53204 【数据加强版】选课
这道题是 P2014 [CTSC1997] 选课 的一个超级数据加强版,原本 O ( n 2 ) O(n^2) O(n2) 地算法只能拿到 50 分。
这道题,如果使用上面给出的代码并略加修改,只能得到 50pts 的好成绩。所以上面的方法在这道题是行不通的。
所以,在这道题里面我将介绍一种新的树形背包方法,也就是在 dfs 序上面进行的奇妙 dp。
这样复杂度是 O ( n m ) O(nm) O(nm) 的,也是非常优秀的了。而且题目保证了 n m ≤ 1 0 8 nm \le 10^8 nm≤108,使用这种方法恰好可以卡过。
接下来开始讲解思路。
考虑先看一棵树,作为例子:
显然我们可以发现,如果最上面的点被选了,那么就可以考虑它最左边的一个儿子。
如果这个儿子被选了,那么就可以继续考虑它最左边的一个儿子。
如果它的左边的儿子已经考虑完了,那么就可以开始考虑右边的儿子。
如果这个儿子没有被选,则显然不能考虑任何一个儿子。
……
最终,考虑的顺序是这样子的:
那么,看到这个东西,你的脑子里面还没有一点点灵感吗?
这不就是 dfs 序嘛!
考虑转移。
如果一个点被选了,它就会转移到下一个 dfs 序代表的位置。
而且,如果一个点没有被选,则其子树所有的点都不能被选!!!完美符合 dfs 序的优秀传统:只需要跳到子树区间右端点 + 1 +1 +1 的位置即可。
所以,这个时候我们就已经把它转换为了一个序列式的 dp,且转移也已经明确,直接跑背包即可。复杂度显然就是 O ( n m ) O(nm) O(nm) 的。
**但是因为这不是相邻进行转移,而是会带有一些跳跃性地转移,所以不能使用滚动数组。空间复杂度也是 O ( n m ) O(nm) O(nm) 的。**但是空间有 500 500 500 MB,所以直接开 int 数组也可以开的下。
个人感觉这种方法非常的优美。
关于实现的一些注意事项:
-
因为数据范围只给了 n m nm nm 的取值,并没有特别地约束 n , m n,m n,m 分别的值,如果开数组的话就会开不下,应该在主函数里面开 vector 二维数组。
-
一开始要让 v a l 0 = 1 val_0 = 1 val0=1,不然后面就无法转移,最后直接把答案减一即可。
其他的看代码就可以了。
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m, x, y;
int val[N], l[N], r[N];
int id[N], dfn;
vector<int> v[N];void dfs(int u) {l[u] = ++dfn, id[dfn] = u;for (auto i : v[u])dfs(i);r[u] = dfn;
}int main() {cin >> n >> m;m++;for (int x = 1; x <= n; x++) {cin >> y >> val[x];v[y].push_back(x);}dfs(0);val[0] = 1;vector<vector<int> > dp(n + 10, vector<int>(m + 10));//二维数组for (int i = 1; i <= n + 1; i++) {int x = id[i];for (int j = 0; j <= m; j++)if (dp[i][j] > 0 || i == 1) {//要判断这是否是合法状态dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i][j] + val[x]);dp[r[x] + 1][j] = max(dp[r[x] + 1][j], dp[i][j]);}}cout << dp[n + 2][m] - 1;return 0;
}
CF815C Karen and Supermarket
仿照日常的树上背包,不难设计出 d p u , n u m , 0 / 1 dp_{u,num,0/1} dpu,num,0/1 表示 u u u 的子树里面选了 n u m num num 个物品, u u u 不使用 / 使用优惠券的最小花费。
考虑如何写出转移。
首先,我们可以不用 u u u,所以子树内也就没有点会被使用:
d p u , i + j , 0 = min ( d p u , i + j , 0 , d p u , i , 0 + d p v , j , 0 ) dp_{u,i+j,0} = \min(dp_{u,i+j,0},dp_{u,i,0}+dp_{v,j,0}) dpu,i+j,0=min(dpu,i+j,0,dpu,i,0+dpv,j,0)
其次,我们可以使用 u u u,且对于 v v v,这个 u u u 的子结点也使用:
d p u , i + j , 1 = min ( d p u , i + j , 1 , d p u , i , 1 + d p v , j , 1 ) dp_{u,i+j,1} = \min(dp_{u,i+j,1},dp_{u,i,1}+dp_{v,j,1}) dpu,i+j,1=min(dpu,i+j,1,dpu,i,1+dpv,j,1)
最后,我们可以使用 u u u,但是对于 v v v 不使用优惠券:
d p u , i + j , 1 = min ( d p u , i + j , 1 , d p u , i , 1 + d p v , j , 0 ) dp_{u,i+j,1} = \min(dp_{u,i+j,1},dp_{u,i,1}+dp_{v,j,0}) dpu,i+j,1=min(dpu,i+j,1,dpu,i,1+dpv,j,0)
考虑初始状态,显然 n u m = 0 num=0 num=0 和 n u m = 1 num=1 num=1 的情况我们会选择特殊考虑。
{ d p u , 0 , 0 = 0 d p u , 1 , 0 = a u d p u , 1 , 1 = a u − b u \begin{cases} dp_{u,0,0} = 0\\ dp_{u,1,0} = a_u \\ dp_{u,1,1} = a_u - b_u \end{cases} ⎩ ⎨ ⎧dpu,0,0=0dpu,1,0=audpu,1,1=au−bu
其他的东西都可以根据这几个初始状态算出来。
答案显然就是找最大的 i i i 来满足 min ( d p 1 , i , 0 , d p 1 , i , 1 ) ≤ m o n e y \min(dp_{1,i,0},dp_{1,i,1}) \le money min(dp1,i,0,dp1,i,1)≤money,其中 m o n e y money money 是她的预算。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5010;
int n, m, a[N], b[N];
int dp[N][N][2], siz[N];
vector<int> v[N];void dfs(int u) {dp[u][0][0] = 0;dp[u][1][0] = a[u];dp[u][1][1] = a[u] - b[u];siz[u] = 1;for (int x : v[u]) {dfs(x);for (int i = siz[u]; i >= 0; i--)for (int j = 0; j <= siz[x]; j++)dp[u][i + j][0] = min(dp[u][i + j][0], dp[u][i][0] + dp[x][j][0]),dp[u][i + j][1] = min(dp[u][i + j][1], dp[u][i][1] + min(dp[x][j][0], dp[x][j][1]));siz[u] += siz[x];}
}signed main() {cin >> n >> m >> a[1] >> b[1];memset(dp, 0x3f, sizeof dp);for (int i = 2, x; i <= n; i++)cin >> a[i] >> b[i] >> x, v[x].push_back(i);dfs(1);for (int i = n; i >= 0; i--)if (min(dp[1][i][0], dp[1][i][1]) <= m) {cout << i;return 0;}return 0;
}
相关文章:
树上背包学习笔记
树上背包,顾名思义,就是在树上跑背包。每日顾名思义 Q:那么到底为什么要树上跑背包 dp 呢? A:因为我们到现在学的背包 dp 还是属于较浅的一类,什么 01 背包、完全背包还是多重背包,但是如果这…...
CPU:为什么Ryzen 7000系列处理器PCIe通道总数是28,而可用的通道数是24?
AMD Ryzen 7000系列(Zen 4架构)处理器的 28条PCIe 5.0通道 中,有 4条固定用于连接主板芯片组(如X670/B650),剩余的 24条直接分配给用户设备。以下是具体分配逻辑: 1. PCIe通道的总分配 24条直连…...
OpenCV 图形API(80)图像与通道拼接函数-----仿射变换函数warpAffine()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 对图像应用仿射变换。 函数 warpAffine 使用指定的矩阵对源图像进行变换: dst ( x , y ) src ( M 11 x M 12 y M 13 , M 21 x M…...
巧记英语四级单词 Unit7-下【晓艳老师版】
navigate v. 航行,航空 那六扇门gatevibrate v.颤抖,抖动 男生早上起来看到六个文胸在那挂着,春心荡漾virtual a.事实上,实际上的 发音“龌龊”;通常lyvia prep.经过 a想成小乌龟,兔子想到河对面吃草&am…...
idea使用lombok错误,找不到符号,明明编译没问题,运行报错
lombok使用出现的问题 问题找不到方法 经常遇到这样的小伙伴看到这个是不是一头雾水,明明我编译没有我问题,运行就出现问题,真的很生气。 下面介绍解决这个问题的几种方法。 开启 annotation processing 开启之后重启,试试有…...
Transformer面经
请问你对Transformer有什么了解 简要回答的话可以这样: Transformer是一种基于自注意力机制的神经网络架构,它主要用于处理序列数据,如自然语言处理。 核心的组件有:自注意力机制(计算序列中每个元素与其他元素的相…...
学习Python的第二天之网络爬虫
30岁程序员学习Python的第二天之网络爬虫的信息提取 BeautifulSoup库 地址:https://beautifulsoup.readthedocs.io/zh-cn/v4.4.0/ 1、BeautifulSoup4安装 在windows系统下通过管理员权限运行cmd窗口 运行pip install beautifulsoup4 测试实例 import requests…...
【基础】Python包管理工具uv使用教程
一、uv简介 uv 是由 Astral(前身为 Basis)团队开发的 Python 包安装器和解析器,完全使用 Rust 语言编写。与传统 Python 工具不同,uv 将多个工具的功能整合到一个高性能的解决方案中,旨在提供更现代、更高效的 Python…...
【十五】Mybatis动态SQL实现原理
Mybatis动态SQL实现原理 目录 Mybatis动态SQL实现原理 概述 动态 SQL 实现原理 总结 概述 每天日常开发都在使用mybatis,但是很多人并没有花心思去理解mybatis的实现原理,一直处于使用阶段,程序员的使命是改变世界,这一点可能…...
UE5 把翅膀动画额外创建动画蓝图并和角色绑定混合动画
把翅膀和角色合并,把翅膀绑在Spine_3上 在5.3内,需要LayerSetup指定骨骼才能使用混合...
Coding Practice,48天强训(30)
Topic 1:爱吃素(素数性质) 爱吃素 在强训25的第一题我总结过关于素数的几种判断方式,如果忘了可以回去看 第一次写我是这样写的 #include <bits/stdc.h> using namespace std;bool isPrime(long long &a, long long …...
华为私有协议Hybrid
实验top图 理论环节 1. 基本概念 Hybrid接口: 支持同时处理多个VLAN流量,且能针对不同VLAN配置是否携带标签(Tagged/Untagged)。 核心特性: 灵活控制数据帧的标签处理方式,适用于复杂网络场景。 2. 工作…...
神经网络之互动练习详解:从基础到拟合非线性数据
神经网络之互动练习详解:从基础到拟合非线性数据 在机器学习的世界里,神经网络是一种强大而神奇的工具,它可以帮助我们解决各种复杂的问题。今天,我们就通过一个有趣的互动练习,来深入了解神经网络的工作原理以及如何…...
遨游科普:2025年,三防平板有多智能?
在极端环境与复杂场景中,专业设备的可靠性始终是行业应用的核心命题。随着物联网、5G通信与边缘计算技术的深度融合,三防平板已突破传统“坚固耐用”的单一属性,进化为集多模通讯、智能感知与场景化扩展于一体的移动智能终端。 AORO P9000三防…...
基于C++的IOT网关和平台7:github项目ctGateway设备协议开发指南
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。 源码指引:github源码指引_初级代码游戏的博客-CSDN博客 系…...
yolov8中的python基础--模块导入篇
import语句有几种不同的写法,它们有不同的用途和优势。 1. 直接 import 语法 import module_name 用途 导入整个模块,使用时需要通过模块名访问其中的内容。 示例 import os print(os.listdir()) # 必须用 os. 前缀 适用场景 当需要频繁使用模块…...
26.2Linux中SPI的驱动实验(编程)_csdn
我尽量讲的更详细,为了关注我的粉丝!!! 这里我们用到的是stm32mp157的板子,所以我们看一下SPI用到的引脚。 1、硬件原理图分析 SPI1_MOSI(对应芯片引脚 SDA/SDI ):主机输出从机输入…...
uv简单使用
通过uv创建项目和虚拟环境 初始化项目 uv init --package my-project 初始化一个名为 my-project 的新项目,并生成必要的文件结构。 创建虚拟环境 uv venv .venv 激活虚拟环境 # For Windows .venv\Scripts\activate# For macOS/Linux source .venv/bin/acti…...
扩增子分析|微生物生态网络稳定性评估之鲁棒性(Robustness)和易损性(Vulnerability)在R中实现
一、引言 周集中老师团队于2021年在Nature climate change发表的文章,阐述了网络稳定性评估的原理算法,并提供了完整的代码。自此对微生物生态网络的评估具有更全面的指标,自此网络稳定性的评估广受大家欢迎。本系列将介绍网络稳定性之鲁棒性…...
线性回归评价标准
In [1]: 12345 import numpy as npfrom sklearn.linear_model import LinearRegressionimport sklearn.datasets as datasets 12 ()diabetesdiabetes $$datasets.load_diabetes In [2]: Out[2]: {‘data’: array([[ 0.03807591,0.05068012,0.06169621,…,-0.00259226, 0.0…...
Qt—鼠标移动事件的趣味小程序:会移动的按钮
1.项目目标 本次根据Qt的鼠标移动事件实现一个趣味小程序:当鼠标移动到按钮时,按钮就会随机出现在置,以至于根本点击不到按钮。 2.项目步骤 首先现在ui界面设计控件(也可以用代码的方式创建,就不多说了) 第一个按钮不需…...
深度解析:2D 写实交互数字人 —— 开启智能交互新时代
在当今数字化浪潮汹涌澎湃的 era,人机交互模式正经历着前所未有的变革与重塑。从最初冷冰冰的机械按键,到如今灵动逼真的数字化形象,交互的内涵不断拓展,已不再局限于信息的单向传递,情感交流、场景融合等多维度需求逐…...
论微服务架构设计及应用
目录 摘要(300~330字) 正文(2000~2500字,2200字为宜) 背景介绍(500字做左右) 论点论据(1500字做左右)...
处理 Clickhouse 内存溢出
一、前情提要 近日,测试服务器配置时,发现当复杂聚合场景的并发度压到20时,会出现clickhouse内存溢出,内存不足报错,如包含Exception: Memory limit (for query)、Exception: Memory limit (total) exceeded等…...
计算机网络复习资料
前情提要https://blog.csdn.net/Liu_Xin233/article/details/134773846?fromshareblogdetail&sharetypeblogdetail&sharerId134773846&sharereferPC&sharesourceLiu_Xin233&sharefromfrom_link第一章 概述 一、计算机网络在信息时代中的作用(…...
数据结构与算法:区间dp
前言 区间dp也是动态规划里很重要的一部分。 一、内容 区间dp的根本原理就是把大范围问题分解成若干小范围的问题去求解。一般来讲,常见的用法有对于两侧端点去展开可能性和对于范围上的划分点去展开可能性。 二、题目 1.让字符串成为回文串的最少插入次数 class Soluti…...
iPaaS制造案例丨某照明行业头部企业借助谷云科技iPaaS步入数字化转型“快车道”
作为国民经济支柱产业,照明灯饰行业历经技术迭代正加速推进数字化转型。从传统照明到智能物联时代,行业领军企业持续探索智能制造升级路径,通过数字化手段重构产业链效率,为产业智能化转型提供标杆示范。 该企业作为国内领先的照明…...
vue3+ts学习!
今天学习一下vue3ts技术! vue3有两种创建方式 (1)vue-cli (2)vite(官方推荐) 所以我用vite创建一个项目 直接在官网上面写一个这个!cmd执行完后,会让你输入项目名称…...
如何使用 QuickAPI 推动汽车行业数据分享:数据仓库场景下的实践
目录 一、行业痛点:数据孤岛与系统复杂性 二、技术转型:从 Hadoop 到华为 DWS 的数据仓库升级 三、引入 QuickAPI:构建统一的数据服务中台 ✅ QuickAPI 的核心能力 四、落地场景实践 1. 经销商管理数据服务化 2. 汽车维保与销售数据整…...
生命游戏(中等)
思路比较简单:复制一份原始数组;根据复制数组中邻居细胞的状态来更新 board 中的细胞状态。 class Solution {public void gameOfLife(int[][] board) {int[] neighbors{0,1,-1};int rowsboard.length;int colsboard[0].length;int[][] copyboardnew i…...
2025 RSAC|大语言模型应用风险与厂商攻防新策略
RSA大会全球影响力及2025年LLM热议概览 作为全球规模最大、影响力最深远的网络安全盛会之一,RSA大会每年汇聚数万名业界人士共商安全趋势。在2025 RSAC上,生成式人工智能(Generative AI)尤其是大型语言模型(LLM&#x…...
深入理解 Linux 阻塞IO与Socket数据结构
一、阻塞IO的直观演示 示例代码:最简单的阻塞接收程序 #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h>int main() {// 创建TCP套接字int sockfd socket(AF_INET, SOCK_STREAM, 0);// 绑定地址端口struct sockaddr_in ad…...
大模型系列(三)--- GPT1论文研读
论文链接: GPT1: Improving Language Understanding by Generative Pre-Training 点评: 首次将Transformer的decoder部分引入无监督训练且引入了辅助训练目标。文章证明无监督预训练显著提升判别任务性能,其中Transformer架构和长依赖文本数…...
14.Three.js 中的 SpotLight(聚光灯)详解与 Vue3 实战示例
在 Three.js 中,SpotLight(聚光灯)是一种能沿着一个方向发射锥形光束的光源,广泛应用于舞台灯光、聚焦灯、手电筒等模拟场景中。本文将详细介绍 SpotLight 的各个属性和使用方法,并提供一个基于 Vue3 Composition API…...
unix 详解
Unix 系统深度解析 一、Unix 起源与历史 Unix 是由 贝尔实验室(AT&T Bell Labs) 的 肯汤普森(Ken Thompson) 和 丹尼斯里奇(Dennis Ritchie) 于 1969 年 开发的操作系统。其诞生背景是: …...
NetSuite 常用类型Item对应Account异同
NetSuite中会有多种类型不同的Item,在期初数据收集的时候我们一般也会让用户提供给我们Item的主数据信息,其中就包含科目部分,但不同类型Item对应科目不完全相同,所以就想帮助自己和各位一起来梳理一下相关内容。 一般我们常用It…...
CentOS配置了镜像源之后依旧下载元数据失败
// 切换到root用户 su root备份原有的镜像源 sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup使用阿里云镜像源 sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo这是清华的…...
mybatis 的多表查询
文章目录 多表查询一对一一对多 多表查询 一对一 开启代码片段编写 专注于 SQL的 编写 JDBC 的写法,注重于 SQL mybatis 在 一对一查询时,核心在于 建立每个表对应的实体类主键根据 主键 id 进行查询,副标根据 设定外键进行查询 在 SQL编写…...
面试常问系列(一)-神经网络参数初始化-之自注意力机制为什么除以根号d而不是2*根号d或者3*根号d
首先先罗列几个参考文章,大家之后可以去看看,加深理解: 面试常问系列(一)-神经网络参数初始化面试常问系列(一)-神经网络参数初始化之自注意力机制_注意力机制的参数初始化怎么做-CSDN博客面试常问系列(一)-神经网络参数初始化-之-softmax-C…...
Linux服务之nginx中http设置及虚拟主机搭建
目录 一.http相关概述 1.mime 2.server下的listen及root 2.1 listen 2.2 root 3.alias别名 4.location相关概述 4.1 语法规则初步解释 5.access模块 6.验证模块 6.1 htpasswd 7.自定义错误页面 8.虚拟主机搭建 (yum安装) 一.http相关概述 h…...
android-ndk开发(7): 从库文件反推ndk版本
android-ndk开发(7): 从库文件反推ndk版本 2025/05/06 1. 概要 对于动态库, 有些能用 parse_elfnote.py 提取,有些不能。 对于静态库, 不能用 parse_elfnote.py 提取; 对于 libopencv_core.a, 可以搜索关键字 General configu…...
MySQL8查询某个JSON类型的字段中出现过的所有键名(json key name)并去重返回
假设我有一张表叫 t1, 其中有一个字段 info 是 JSON类型,现在我想查询 t1.info 字段中出现过的所有键名,MySQL提供了一个函数 JSON_KEYS(column) 来返回单条数据单个JSON字段中的所有键名组成的集合,那我想查询整个表所有记录中某个JSON字段出…...
【AI】基于生活案例的LLM强化学习(入门帖)
一、从“教小孩说话”到“教模型说话”:LLM 训练全貌 1. 先打个比方 第一阶段:预训练 就好比教一个小孩先“读很多书”,让他获得基本的语言能力。对 LLM 来说,就是在海量文本上进行“预测下一个词”的训练,从而学到“…...
如何通过代理 IP 实现异地直播推流
在直播行业日益火爆的今天,许多主播希望突破地域限制,实现异地直播推流,以获得更广泛的观众群体和更好的直播效果。代理 IP 作为一种有效的网络工具,能够帮助主播轻松达成这一目标。本文将详细介绍如何通过代理 IP 实现异地直播推…...
Linux 网络编程 day5 多路IO转接之改进select and poll
三种多路IO转接方法:select , poll , epoll 改进select多路IO转接,使用数组来保存含有需要连接的套接字cfd,不用循环至1024,节约时间提高效率。 #include<stdio.h> #include<stdlib.h> #in…...
【iOS】源码阅读(二)——NSObject的alloc源码
文章目录 前言问题发现探索NSObject的alloc源码实现流程探索NSObject为什么直接走objc_alloc,而GGObject先走alloc总结 前言 前面笔者已经学习了alloc相关源码,之前的alloc底层源码实现步骤是以GGObject为基础的,今天我们来探索一下NSObject中…...
如何在短时间内高效复习食品安全员考试?
以下是一些在短时间内高效复习食品安全员考试的方法: 制定科学计划:根据剩余时间和考试内容,将备考时间划分为基础学习、强化巩固和模拟冲刺三个阶段。如基础学习阶段可安排每天学习 2-3 小时,梳理教材知识;强化巩固阶…...
Kotlin空安全解决Android NPE问题
在 Android 开发中,NullPointerException(NPE)一直是最常见的崩溃类型之一。Kotlin 通过创新的空安全机制,在语言层面彻底解决了这一问题。以下是 Kotlin 空安全的核心要点和实战指南: 一、Kotlin 空安全设计哲学 编译期防御:通过类型系统强制区分可空(?)与非空类型显…...
PrimExpr 与 RelayExpr 的区别
PrimExpr 与 RelayExpr 的区别解析 在 TVM 的表达式系统中,PrimExpr 和 RelayExpr 是两种不同层级的表达式类型,分别服务于 TVM 的不同编译阶段和目标场景。以下是它们的核心区别和关联: 1. 设计目标与层级 特性PrimExprRelayExpr所属层级TV…...
R语言助力森林生态研究:从数据处理到群落稳定性分析的完整流程,结合机器学习与案例写作
在生态学研究中,森林生态系统的结构、功能与稳定性是核心研究内容之一。这些方面不仅关系到森林动态变化和物种多样性,还直接影响森林提供的生态服务功能及其应对环境变化的能力。 👉 森林生态系统的结构、功能与稳定性是生态学研究的核心。…...