数据结构与算法学习笔记(Acwing 提高课)----动态规划·树形DP

news2025/6/7 2:53:13

数据结构与算法学习笔记----动态规划·树形DP

@@ author: 明月清了个风
@@ first publish time: 2025.6.4

ps⭐️树形动态规划(树形DP)是处理树结构问题的一种动态规划方法,特征也很明显,会有一个树形结构,其实是DFS的优化。

Acwing 1072. 树的最长路径

给定一棵树,树中包含 n n n个节点(编号 1 ∼ n 1 \sim n 1n)和 n − 1 n - 1 n1条无向边,每条边都有一个权值。

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

换句话说,要找到两个点,使得他们之间的距离最远。

输入格式

第一行包含整数 n n n

接下来 n − 1 n - 1 n1行,每行包含三个整数 a i , b i , c i a_i, b_i,c_i ai,bi,ci,表示点 a i a_i ai b i b_i bi之间存在一条权值为 c i c_i ci的边。

输出格式

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

数据范围

1 ≤ n ≤ 10000 1 \le n \le 10000 1n10000,

1 ≤ a i , b i ≤ n 1 \le a_i,b_i \le n 1ai,bin,

1 ≤ c i ≤ 10 5 1 \le c_i \le 10^5 1ci105

思路

找树的最长路径(直径)有一个通用的思路:

  1. 任选一个点,找出离这个点最远的点 u u u
  2. 再找到离 u u u最远的点 v v v

u u u v v v之间的路径就是直径。

证明如下;

假设任选的这个点是 a a a,找到离他最远的点为 u u u,只要证明 u u u是某条直径的一个端点就行了。

假设一条直径为 b c bc bc,那他可能会与 a u au au之间没有交点,由于树是连通的,所以从 a a a开始走一定能走到 c c c点,假设这条路径是 a x y c axyc axyc,其中 x x x a u au au上, y y y b c bc bc上,由于 u u u是离 a a a最远的点,那么 x u xu xu的长度大于等于 x y + y c xy + yc xy+yc,那么就有 b y + y x + x u ≥ y c by + yx + xu \ge yc by+yx+xuyc,因此 b u bu bu之间的距离一定大于等于 b c bc bc的长度,因此 b u bu bu一定是一条直径的端点。

另一种情况是两条线相交,假设交点是 x x x,那么由于 u u u是离 a a a最远的点,就有 u x ≥ x c ux \ge xc uxxc,那么 b x + x u ≥ b c bx + xu \ge bc bx+xubc,因此 u u u也一定是一条直径的端点。

在这里插入图片描述

由于这道题目并没有指定根节点,因此可以任选一个点将整棵树构建起来,然后对于每个点记录经过该点的最长路径。

对于一个点的最长路径,对于每个点来说可以分为两种情况,一种是往下走,一种是往上走。就是枚举他的每个子节点存的最大距离再加上他到这个子节点的距离;另一种情况是穿过一个点的路径,那么就可以计算这个点往下的最长的路径以及第二长的路径相加。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 10010, M = N * 2;

int n;
int h[N], e[M], ne[M], w[M], idx;
int ans;

void add(int a, int b, int c)
{
    w[idx] = c, e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

int dfs(int u, int father)
{
    int dist = 0;
    int d1 = 0, d2 = 0;
    
    for(int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if(j == father) continue;
        
        int d = dfs(j, u) + w[i];
        dist = max(dist, d);
        
        if(d >= d1)
        {
            d2 = d1;
            d1 = d;
        } else if(d > d2) d2 = d;
    }
    
    ans = max(ans, d1 + d2);
    return dist;
}

int main()
{
    cin >> n;
    
    memset(h, -1, sizeof h);
    for(int i = 0; i < n - 1; i ++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c), add(b, a, c);
    }
    
    dfs(1, -1);
    
    cout << ans << endl;
    
    return 0;
}

Acwing 1073. 树的中心

给定一棵树,树中包含 n n n个节点(编号 1 ∼ n 1 \sim n 1n)和 n − 1 n - 1 n1条无向边,每条边都有一个权值。

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

输入格式

第一行包含整数 n n n

接下来 n − 1 n - 1 n1行,每行包含三个整数 a i , b i , c i a_i, b_i,c_i ai,bi,ci,表示点 a i a_i ai b i b_i bi之间存在一条权值为 c i c_i ci的边。

输出格式

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

数据范围

1 ≤ n ≤ 10000 1 \le n \le 10000 1n10000,

1 ≤ a i , b i ≤ n 1 \le a_i,b_i \le n 1ai,bin,

1 ≤ c i ≤ 10 5 1 \le c_i \le 10^5 1ci105

思路

与上一题一样,对于树中的一点有向上走与向下走两种方案,每个点都记录一个向上走与向下走的最大值,假设点 2 2 2向其父节点 1 1 1走,那么这就是向上走,在 1 1 1点可以继续向上走,也可以向下不经过点 2 2 2的子节点走,若向下走,那就要考虑点 2 2 2是否是向下走的最大长度,如果是,那就使能选择次大值更新。

这一题复杂的地方在于,更新的过程同时用到了子节点更新父节点和父节点更新子节点。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 100010, M = N * 2, inf = 0x3f3f3f3f;

int n;
int h[N], e[M] ,w[M], ne[M], idx;
int d1[N], d2[N], up[N];
int p1[N], p2[N];

void add(int a, int b, int c)
{
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}

int dfs_d(int u, int father)
{
    if(h[u] == -1) return 0;
    
    d1[u] = d2[u] = -inf;
    
    for(int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if(j == father) continue;
        int d = dfs_d(j, u) + w[i];
        if(d >= d1[u])
        {
            d2[u] = d1[u], d1[u] = d;
            p2[u] = p1[u], p1[u] = j; // 记录最大值和次大值是从向哪个子节点走的
        } else if(d > d2[u])
            d2[u] = d, p2[u] = j;
    }
    
    if(d1[u] == -inf) d1[u] = d2[u] = 0; // 如果是叶子结点无法往下,置为0
    
    return d1[u];
}


int dfs_u(int u, int father)
{
    if(h[u] == -1) return 0;
    
    for(int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if(j == father) continue;
        
        if(p1[u] == j) up[j] = max(up[u], d2[u]) + w[i];
        else up[j] = max(up[u], d1[u]) + w[i];
        
        dfs_u(j, u);
    }
}

int main()
{
    cin >> n;
    
    memset(h, -1, sizeof h);
    
    for(int i = 0; i < n - 1; i ++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c), add(b, a, c);
    }
    
    dfs_d(1, -1);
    dfs_u(1, -1);
    
    int res = inf;
    for(int i = 1; i <= n; i ++) res = min(res, max(up[i], d1[i]));
    
    cout << res << endl;
    
    return 0;
    
}

Acwing 1075. 数字转换

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

例如 4 4 4可以变成 3 3 3 1 1 1可以变成 7 7 7

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

输入格式

输入一个正整数 n n n

输出格式

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

数据范围

1 ≤ n ≤ 50000 1 \le n \le 50000 1n50000

思路

对于每个数 x x x都会有一个约数之和 y y y与之对应,且 x x x y y y的关系是唯一的,但需要注意的是 y y y可能会对应于多个数,因此要将 y y y作为父节点。那么对于所有数就可以构建出一堆树(注意不是一棵树,因为不一定所有数都能连通),最多变换步数就是这堆树中最长的树的直径,就是上面的第一题。

问题就是建树,也就是找到 1 ∼ n 1 \sim n 1n中所有数的约数之和。当然可以枚举每个数进行计算(试除法),但是如果 n n n的范围进一步扩大就会超时。可以反向思考,不是求每个数的约数是哪些数,而是求每个数是哪些数的约数,也就是枚举每个数的倍数

for(int i = 1; i <= n; i ++)
    for(int j = 2; j * i <= n; j ++)  // 从2开始枚举

这样的时间复杂度是 n ln ⁡ n n \ln{n} nlnn,因为 n + n 2 + n 3 + ⋯ n + \frac{n}{2} + \frac{n}{3} + \cdots n+2n+3n+是一个调和级数,

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 50010;

int n;
int sum[N];
int h[N], e[N], ne[N], idx;
bool st[N];
int ans;

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

int dfs(int u)
{
    int d1 = 0, d2 = 0;
    for(int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        int d = dfs(j) + 1;
        if(d >= d1) d2 = d1, d1 = d;
        else if(d > d2) d2 = d;
    }
    
    ans = max(ans, d1 + d2);
    return d1;
}

int main()
{
    cin >> n;
    
    memset(h, -1, sizeof h);
    
    for(int i = 1; i <=n; i ++)
        for(int j = 2; j <= n / i; j ++)
            sum[i * j] += i;
            
    for(int i = 2; i <= n; i ++)  // 建立边的时候要从2开始,因为对于1来说,他会和0建边,题目要求是正整数。
        if(sum[i] < i)
        {
            add(sum[i], i);
            st[i] = true;
        }
    
    for(int i = 1; i <= n; i ++)
        if(!st[i])
            dfs(i);
    
    cout << ans << endl;
    
    return 0;
}

Acwing 1074. 二叉苹果树

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

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

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

一棵苹果树的树枝太多了,需要剪枝,但是一些树枝上长有苹果,给定需要保留的树枝数量,求最多能留住多少苹果,这里的保留是指最终与 1 1 1号点连通。

输入格式

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

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

输出格式

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

数据范围

1 < Q < N ≤ 100 1 < Q < N \le 100 1<Q<N100

每根树枝上苹果不超过 30000 30000 30000个。

思路

在[背包模型四](数据结构与算法学习笔记(Acwing提高课)----动态规划·背包模型(四)-CSDN博客)中讲过一道有依赖的背包问题,其实这道题和那道题是一样的,将苹果数量放到每个点上,要选择一个点就要选择它的父节点,将所有点的体积看为 1 1 1,总的体积就是 Q Q Q

但是这题可以进一步简化,使用 f [ i ] [ j ] f[i][j] f[i][j]表示以 i i i为根的子树中选择 j j j个树枝的最大价值。

对于状态划分来说,对于每个具有两个分岔的小子树,将其两个子节点看成是一个分组背包问题里的两个物品组,也就是对于以 i i i为根的子树有两个物品 s 1 s_1 s1 s 2 s_2 s2,划分为在 s 1 s_1 s1中选择 0 0 0条边,那就是 f [ s 1 ] [ 0 ] f[s_1][0] f[s1][0];选择 1 1 1条边,那就是 f [ s 1 ] [ 1 ] f[s_1][1] f[s1][1];以此类推,最多是 f [ s 1 ] [ j − 1 ] f[s_1][j - 1] f[s1][j1],因为要选择 s 1 s_1 s1就要选择 i i i,也就是必选 i → j i \rightarrow j ij这条边,当然计算的时候要加上这条边的权重。对于子树 s 2 s_2 s2也是一样的。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 110, M = N * 2;

int n, m;
int f[N][N];
int h[N], e[M], ne[M], w[M], idx;

void add(int a, int b, int c)
{
    w[idx] = c, e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

void dfs(int u, int father)
{
    for(int i = h[u]; i != -1; i = ne[i])  // 枚举物品组
    {
        if(e[i] == father) continue;
        dfs(e[i], u);
        
        for(int j = m; j >= 0; j --) // 体积
            for(int k = 0; k < j; k ++) // 决策
                f[u][j] = max(f[u][j], f[u][j - k - 1] + f[e[i]][k] + w[i]);
    }
}

int main()
{
    cin >> n >> m;
    
    memset(h, -1, sizeof h);
    for(int i = 0; i < n - 1; i ++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c), add(b, a, c);
    }
    
    dfs(1, -1);
    
    cout << f[1][m] << endl;
    
    return 0;
}

Acwing 323. 战略游戏

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

现在他有以下问题。

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

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

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

你能帮助他吗?

例如,下面的树:

在这里插入图片描述

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

输入格式

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

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

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

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

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

输出格式

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

数据范围

0 < N ≤ 1500 0 < N \le 1500 0<N1500

思路

这道题的题意是对于一颗树,选择最少的节点数覆盖所有的边,这个其实和没有上司的舞会很像,在没有上司的舞会中,我们求的是每条边上最多仅选择一个点求最大值,属于最大独立集问题,而这道题中,每条边上至少选择一个点求最小值,这两个是对称的问题。

状态计算和状态转移也很简单,直接看代码叭。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 1600;

int n;
int f[N][2];
int h[N], e[N], ne[N], idx;
bool st[N];

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

void dfs(int u)
{
    f[u][0] = 0;
    f[u][1] = 1;
    
    for(int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        
        dfs(j);
        
        f[u][0] += f[j][1];
        f[u][1] += min(f[j][0], f[j][1]);
    }
}

int main()
{
    while(scanf("%d", &n) != -1)
    {
        idx = 0;
        memset(h, -1, sizeof h);
        memset(st, 0, sizeof st);
        
        for(int i = 0; i < n; i ++)
        {
            int cnt;
            int id;
            scanf("%d:(%d)", &id, &cnt);
            
            while(cnt --)
            {
                int ver;
                cin >> ver;
                add(id, ver);
                st[ver] = true;
            }
            
        }
        int root = 0;
        while(st[root]) root ++;
            
        dfs(root);
        cout << min(f[root][1], f[root][0]) << endl;
    }
    
    return 0;
}

Acwing 1077. 皇宫看守

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

皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状,某些宫殿间可以互相望见。

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

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

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

输入格式

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

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

第二行至第 n + 1 n + 1 n+1行,每行描述每个宫殿结点信息,依次为:该宫殿结点标号为 i i i,在该宫殿内安置侍卫所需的经费 k k k,该边的儿子数 m m m,接下来 m m m个数,分别是这个结点的 m m m个儿子的编号 r 1 , r 2 , ⋯   , r m r_1, r_2, \cdots, r_m r1,r2,,rm

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

输出格式

输出最少的经费。

数据范围

0 < N ≤ 1500 0 < N \le 1500 0<N1500

思路

在这题中,同样是挑选足够的点完成整颗树的覆盖,但是对于每条边来说,这一题的状态表示与之前并不一样,使用 f [ i ] [ 0 ] f[i][0] f[i][0]表示点 i i i被父节点看到的最小花费, f [ i ] [ 1 ] f[i][1] f[i][1]表示点 i i i被子节点看到的最小花费, f [ i ] [ 2 ] f[i][2] f[i][2]表示点 i i i上摆放守卫的最小花费。

对于状态转移,当节点状态为 f [ i ] [ 0 ] f[i][0] f[i][0]时,那么他的最小花费就是他的所有子节点状态为 1 1 1 2 2 2时的和,但是他的子节点不可能是 0 0 0,因为 i i i 0 0 0,表示没有放侍卫,就不可能看到他的子节点,所以他的子节点只能是另外两种状态;当节点状态为 f [ i ] [ 2 ] f[i][2] f[i][2]时,它的子节点可以是三种状态,因为它上面放了侍卫;当节点状态为 f [ i ] [ 1 ] f[i][1] f[i][1]时,表示他是被子节点看到的,因此需要枚举是哪个子节点看到的它,然后取最小值就行,假设是 k k k这个结点看到了 i i i,那么一定要有 f [ k ] [ 2 ] f[k][2] f[k][2],其他的子节点可以是 1 1 1 2 2 2

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1510;

int n;
int f[N][3];
int h[N], e[N], w[N], ne[N], idx;
bool st[N];

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

void dfs(int u)
{
    f[u][2] = w[u];
    
    for(int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        
        dfs(j);
    
        f[u][0] += min(f[j][1], f[j][2]);
        f[u][2] += min(f[j][0], min(f[j][1], f[j][2]));
    }
    
    f[u][1] = 1e9;
    
    for(int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i]; // 枚举是哪个子节点看到当前节点u
        
        f[u][1] = min(f[u][1], f[j][2] + f[u][0] - min(f[j][1], f[j][2]));
    }
}

int main()
{
    cin >> n;
    
    memset(h, -1, sizeof h);
    for(int i = 1; i <= n; i ++)
    {
        int id, cnt, cost;
        cin >> id >> cost >> cnt;
        w[id] = cost;
        while(cnt --)
        {
            int ver;
            cin >> ver;
            add(id, ver);
            st[ver] = true;
        }
    }
    
    int root =  1;
    while(st[root]) root ++;
    
    dfs(root);
    
    cout << min(f[root][1], f[root][2]) << endl;
    
    return 0;
}

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

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

相关文章

leetcode hot100刷题日记——36.最长连续序列

解答&#xff1a; 实际上在哈希表中存储不重复的数字。 然后遍历哈希表&#xff0c;找间隔&#xff0c;更新最大间隔。 class Solution { public:int longestConsecutive(vector<int>& nums) {unordered_set<int>hash;for(int num:nums){hash.insert(num);}in…

CentOS7关闭防火墙、Linux开启关闭防火墙

文章目录 一、firewalld开启、关闭防火墙1、查看防火墙状态 一、firewalld开启、关闭防火墙 以下命令在linux系统CentOS7中操作开启关闭防火墙 # 查询防火墙状态 systemctl status firewalld.service # 开启防火墙 systemctl start firewalld.service # 开机自启动防火墙 syste…

PyTorch——搭建小实战和Sequential的使用(7)

import torch from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linearclass TY(nn.Module):def __init__(self):"""初始化TY卷积神经网络模型模型结构&#xff1a;3层卷积池化&#xff0c;2层全连接设计目标&#xff1a;处理32x32像素的…

Python 开发效率秘籍:PyCharm、VS Code 与 Anaconda 配置与实战全解

目录 一、IDE(集成开发环境)是什么?二、Python IDE有哪些&#xff0c;哪款适合初学者&#xff1f;三、Visual Studio Code下载和安装教程3.1 VS Code下载和安装3.2 VS Code运行Python程序 四、PyCharm下载和安装教程4.1 PyCharm下载4.2 PyCharm安装4.3 运行PyCharm4.4 创建工程…

大话软工笔记—组合要素1之要素

1. 要素来源 对象是要素的来源&#xff0c;要素是从对象分解而来的。可将对象分为优化类和非优化类&#xff0c;如下图所示。 对象分类图 2. 要素的概念 2.1 要素的定义 要素&#xff0c;是构成事物必不可少的因素&#xff0c;要素的集合体构成了对象。 2.2 要素的内容 要…

平台化 LIMS 系统架构 跨行业协同与资源共享的实现路径

在科技快速发展的今天&#xff0c;质检行业正面临着效率、合规和数据安全的多重挑战。新一代质检 LIMS 系统以智能化与平台化为核心&#xff0c;为实验室管理提供了全新的解决方案。 一、智能化&#xff1a;从数据采集到分析的全流程升级 传统质检流程中&#xff0c;人工数据录…

RedisTemplate查询不到redis中的数据问题(序列化)

RedisTemplate查询不到redis中的数据问题(序列化) 一.问题描述 存入Redis中的值取出来却为null,问题根本原因就是RedisTemplate和StringRedisTemplate的序列化问题、代码示例&#xff1a; SpringBootTest class Redis02SpringbootApplicationTests {Autowiredprivate RedisTe…

SkyWalking如何实现跨线程Trace传递

一、概述 SkyWalking 的中构建 Trace 信息时会借助 ThreadLocal来存储一些上下文信息&#xff0c;当遇到跨线程的时候&#xff0c;如果 Trace 的上下文信息没有传递到新线程的ThreadLocal 中&#xff0c;那么链路就断开了。那么SkyWalking是如何解决这个问题的呢&#xff1f; …

使用 Spring Boot 3.3 和 JdbcTemplate 操作 MySQL 数据库

在现代的 Java 应用开发中&#xff0c;Spring Boot 提供了强大的工具来简化数据库操作。JdbcTemplate 是 Spring 提供的一个核心类&#xff0c;用于简化 JDBC 操作&#xff0c;减少样板代码。本文将介绍如何在 Spring Boot 3.3 项目中使用 JdbcTemplate 来操作 MySQL 数据库&am…

Axure高保真LayUI框架 V2.6.8元件库

点击下载《Axure高保真LayUI框架 V2.6.8元件库》 原型效果&#xff1a;https://axhub.im/ax9/bf36e6dd89bc4c9f/#g1 摘要 本文详细阐述了在 Axure 环境下打造的一套高度还原 LayUI 框架的组件元件集。通过对 LayUI 框架组件的深入剖析&#xff0c;结合 Axure 的强大功能&…

通讯录实现(Linux+Cpp)

通讯录实现&#xff08;LinuxCpp&#xff09; 产品底层思考&#xff1a; 人员如何存储 -> 链表 &#xff08;增删改 但是排序不适合&#xff09; 文件存储 -> 人员数据的格式 name:xxx,phone:xxx 人员信息 -> 姓名、电话 引出2 name: xxx,phone: xxx,age: xxx,addr…

质检 LIMS 系统数据防护指南 三级等保认证与金融级加密方案设计

面对频发的数据泄露事件&#xff0c;企业亟需构建一套 “防得住、追得回、打得赢” 的防护体系。质检 LIMS 系统通过三级等保认证与金融级加密的结合&#xff0c;为这一目标提供了可行路径。 一、金融级加密&#xff1a;构建数据防护的 “铜墙铁壁” 金融级加密技术通过协议加密…

Spring Boot 从Socket 到Netty网络编程(上):SOCKET 基本开发(BIO)与改进(NIO)

前言 无论是软件还是硬件的本质都是要解决IO问题&#xff08;输入、输出&#xff09;&#xff0c;再说回网络编程本质上都是基于TCP/UP的开发&#xff0c;socket是在此基础上做的扩展与封装&#xff0c;而Netty又是对socket做的封装。本文旨在通过相关案例对socket进行探讨。 一…

79. Word Search

题目描述 79. Word Search 回溯 代码一&#xff0c;使用used数组 class Solution {vector<pair<int,int>> directions{{0,1},{0,-1},{1,0},{-1,0}};vector<vector<bool>> used; public:bool exist(vector<vector<char>>& board, st…

结构性设计模式之Facade(外观)设计模式

结构性设计模式之Facade&#xff08;外观&#xff09;设计模式 前言&#xff1a; 外观模式&#xff1a;用自己的话理解就是用户看到是一个总体页面&#xff0c;比如xx报名系统页面。里面有历年真题模块、报名模块、教程模块、首页模块… 做了一个各个模块的合并&#xff0c;对…

ICML 2025 Spotlight | 机器人界的「Sora」!让机器人实时进行未来预测和动作执行!

标题&#xff1a;Video Prediction Policy: A Generalist Robot Policy with Predictive Visual Representations 作者&#xff1a;Yucheng Hu, Yanjiang Guo, Pengchao Wang, Xiaoyu Chen, Yen-Jen Wang, Jianke Zhang, Koushil Sreenath, Chaochao Lu, Jianyu Chen 机构&am…

AI生态警报:MCP协议风险与应对指南(下)——MCP Host安全

AI生态警报&#xff1a;MCP协议风险与应对指南&#xff08;上&#xff09;——架构与供应链风险https://blog.csdn.net/WangsuSecurity/article/details/148335401?sharetypeblogdetail&sharerId148335401&sharereferPC&sharesourceWangsuSecurity&spm1011.24…

基于VLC的Unity视频播放器(四)

上篇文章中提到的问题 播放某个m3u8地址时会嘎掉&#xff0c;想办法解决了一下&#xff0c;很粗暴的&#xff0c;先SetFormat&#xff0c;再Stop&#xff0c;最后再Play&#xff0c;能用…… if (player ! null && player.GetSize() 0) {player.GetSize((w, h) >…

pixel刷入Android15 userdebug版本

最近入手一个pixel7,想着刷个userdebug版本&#xff0c;就不用模拟器调试开发了&#xff0c;结果按照网上的教程&#xff0c;每次刷机后都是卡在goole logo界面&#xff0c;卡了一天多我才找到问题所在&#xff0c;想着记录下&#xff0c;给自己做个备份。 1. 前期准备&#x…

C# 一个解决方案放一个dll项目,一个dll测试项目 ,调试dll项目的源码

一个解决方案&#xff08;sln&#xff09;中放入2个项目(project&#xff0c;通常是一个文件夹)&#xff0c;一个dll项目&#xff0c;一个dll测试项目 右键dll测试项目&#xff0c;设为启动项目。 在dll测试项目添加引用 1&#xff09;右键测试项目 → 添加 → 引用 → 项目…