当前位置: 首页 > news >正文

最短路算法——差分约束

差分约束

(1) 求不等式组的可行解

  • 源点:从源点出发,一定可以走到所有的边
  • 求可行解步骤:
    • 先将每个不等式 x i ≤ x j + c x_i \le x_j + c xixj+c,转化成一条从 s j s_j sj走到 s i s_i si,长度为 c k c_k ck 的一条边
    • 找一个超级源点,使得该源点一定可以遍历到所有边
    • 从源点求一遍单源最短路
      • 结果一:如果存在负环,则原不等式组一定无解
      • 结果二:如果没有负环,则 d i s t [ i ] dist[i] dist[i]就是原不等式组的一个可行解

(2) 如何求最大值或最小值

  • 结论: 如果求的是最小值,则应该求最长路;如果求的是最大值,则应该求最短路;
  • 问题1:如何转化 x i ≤ c x_i \le c xic,其中c是一个常数
    • 方法:建立一个超级源点,0,然后建立0->i,长度是c的边即可。
    • 以求 x i x_i xi的最大值为例:求所有从 x i x_i xi出发,构成的不等式链 x i ≤ x j + c j ≤ x k + c 2 + c 1 ≤ . . . ≤ c 1 + c 2 + . . . x_i \le x_j+c_j \le x_k + c_2 + c_1 \le ...\le c_1+c_2+... xixj+cjxk+c2+c1...c1+c2+...所计算出的上界(而这个上界要让所有关系都成立,那么就必须以最小的上界为上界,因此需要用最短路算法求到i这个点的最短距离)

(3) 关系:

每一个差分约束的问题都可以转换成最短路的问题

理论理解

题单

1. 糖果

第一眼:

  • 感觉和floyd的排序那一道题有点相似之处,两个点之间都有关系(ps:关系闭包)
  • 排序不一样的地方在于,这道题确定小朋友各种胡搅蛮缠的糖多糖少要求后,老师需要准备的糖个数的最小值

思考:

  • 怎么去结合这两种题目要求呢,一开始能想到的处理就是先处理关系闭包问题,同时用一个ans去记录老师需要准备的糖的数量从最少的1个开始,关系环到一个一个往后的大于关系也只是加1(这个时候又想到记录方案数那题),如果是相等的关系,当前节点的方案数是前一点的一倍,如果大于关系,当前节点的方案数等于前个节点加一,最后老师需要准备糖果的个数就是总的方案数,该觉还是可以spfa走一波,开一个cnt数组那样子
    • 这样要怎么考虑所有关系呢

听y说:

  • 二刷视频
    • 我悟了。就是这题它并没有直接给出我需要给某个小朋友多少糖,只给出了每个小朋友糖的相对数量关系,而我们需要一个超级源点,去遍历到所有的边。
    • 关于求最小值用最长路建边并做spfa求最长路,
#include<bits/stdc++.h>using namespace std;
#define int long long
int n,k;
const int N=1e5+10,M=3*N;
int h[N],e[M],ne[M],w[M],idx;
int d[N],q[N],st[N],cnt[N];void add(int a,int b,int c){e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}bool spfa(){memset(d,-0x3f,sizeof d);d[0]=0;int hh=0,tt=1;q[hh]=0;while(hh!=tt){int t=q[--tt];if(tt==N) tt=0;st[t]=0;for(int i=h[t];i!=-1;i=ne[i]){int j=e[i];if(d[j]<d[t]+w[i]){d[j]=d[t]+w[i];cnt[j]=cnt[t]+1;if(cnt[j]>=n+1) return 0;if(!st[j]){st[j]=1;q[tt++]=j;if(tt==N)tt=0;}}}}return 1;
}signed main(){scanf("%lld%lld",&n,&k);memset(h,-1,sizeof h);for(int i=0;i<k;i++){int x,a,b;scanf("%lld%lld%lld",&x,&a,&b);if(x==1) add(b,a,0),add(a,b,0);else if(x==2) add(a,b,1);else if(x==3) add(b,a,0);else if(x==4) add(b,a,1);else if(x==5) add(a,b,0);}for(int i=1;i<=n;i++) add(0,i,1);int res=spfa();if(!res){puts("-1");}else{res=0;for(int i=1;i<=n;i++) res+=d[i];printf("%lld",res);}return 0;
}

先进先出的栈

image-20240706165814290

2. 区间

第一眼:

  • 如果要让Z包含的数尽可能少,那就让一个区间的数集中在和其他区间相交的部分就可以贪心的解决这个问题了吧

听y说:

  • 用差分约束的思想做很牛逼,同时利用前缀和的思想,绝绝子
  • 两个端点约束关系:
    • s [ i ] ≥ s [ i − 1 ] s[i] \ge s[i-1] s[i]s[i1]
    • $s[i]-s[i-1] \le 1 $
    • [ a , b ] [a,b] [a,b] s [ b ] − s [ a − 1 ] ≥ c s[b]-s[a-1] \ge c s[b]s[a1]c
  • 转换成最短路模型——求最长路
    • s [ i ] ≥ s [ i − 1 ] s[i] \ge s[i-1] s[i]s[i1]
    • s [ i − 1 ] ≥ s [ i ] − 1 s[i-1] \ge s[i] -1 s[i1]s[i]1
    • s [ b ] ≥ s [ a − 1 ] + c s[b] \ge s[a-1]+c s[b]s[a1]+c
  • 接着就是模版框框的打了
#include<bits/stdc++.h>using namespace std;
//关于这里的N和M的取值,因为M代表边数,我们以最大值N建边
//最多会建3*N条边,如果也算上第N个点的位置的话,会数组越界,可以开大一个数量级
//因为并没有特别熟练空间复杂度以及并不料想到后他数据怎么卡,就开大一个数量级过了
const int N=5e4+10,M=4*N+10;
int m;
int h[N],e[M],w[M],ne[M],idx;
int d[N],st[N],cnt[N],q[N];void add(int a,int b,int c){e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;  
}bool spfa(){memset(d,-0x3f,sizeof d);d[0]=0;int hh=0,tt=1;while(hh!=tt){int t=q[hh++];if(hh==N) hh=0;st[t]=0;for(int i=h[t];i!=-1;i=ne[i]){int j=e[i];if(d[j]<d[t]+w[i]){d[j]=d[t]+w[i];if(!st[j]){st[j]=1;q[tt++]=j;if(tt==N) tt=0;}}}}}signed main(){scanf("%d",&m);memset(h,-1,sizeof h);for(int i=1;i<N;i++){add(i-1,i,0);add(i,i-1,-1);}while(m--){int a,b,c;scanf("%d%d%d",&a,&b,&c);a++,b++;add(a-1,b,c);}spfa();printf("%d",d[50001]);return 0;
}
3. 排队布局

第一眼:

  • 又是usaco的牛,好多事的牛
    • 1和n之间可以任意大,说明1或n都没有能够约束他们的其他牛
    • 不存在满足要求,是不是两头牛之间的约束关系会存在矛盾

思考:

  • 学差分约束的时候时把这道题和糖果(第一题)进行着对比来学的

    • 糖果——求最小值——求最长路
    • 本题——求最大值
  • 索性先自己思考并落实一遍

    • 两头牛之间距离差分约束关系
      • 原本编号的先后顺序: s [ i ] < = s [ i + 1 ] s[i]<=s[i+1] s[i]<=s[i+1]
      • M L M_L ML条边: s [ a ] − s [ b ] ≤ c s[a]-s[b] \le c s[a]s[b]c
      • M D M_D MD条边: s [ a ] − s [ b ] ≥ c s[a]-s[b] \ge c s[a]s[b]c
    • 最短路;
      • s [ i ] < = s [ i + 1 ] s[i]<=s[i+1] s[i]<=s[i+1]
      • s [ a ] ≤ s [ b ] + c s[a] \le s[b]+c s[a]s[b]+c
      • s [ b ] ≤ s [ a ] − c s[b] \le s[a]-c s[b]s[a]c
    • Tips:
  • 为什么n一定能到其他所有边?

    • 因为第一条约束关系
  • 隐含的前缀和思想

#include<bits/stdc++.h>using namespace std;
//需要思考怎么建边,约束条件如何化成边
const int N=1e3+10,M=2e4+10+2*N,INF=0x3f3f3f3f;
int n,l,d;
int h[N],e[M],w[M],ne[M],idx;
int dist[N],st[N],cnt[N],q[N];void add(int a,int b,int c){e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}int spfa(int s){memset(dist,0x3f,sizeof dist);memset(st,0,sizeof st);memset(cnt,0,sizeof cnt);dist[s]=0;int hh=0,tt=1;q[hh]=s;while(hh!=tt){int t=q[hh++];if(hh==N) hh=0;st[t]=0;for(int i=h[t];i!=-1;i=ne[i]){int j=e[i]; if(dist[j]>dist[t]+w[i]){dist[j]=dist[t]+w[i];cnt[j]=cnt[t]+1;if(cnt[j]>=n+1) return -1;if(!st[j]){st[j]=1;q[tt++]=j;if(tt==N) tt=0;}}}}return 1;
}signed main(){cin>>n>>l>>d;memset(h,-1,sizeof h);for(int i=1;i<n;i++){add(i+1,i,0);add(0,i,0);}add(0,n,0);for(int i=0;i<l;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);if(a>b) swap(a,b);add(a,b,c);}for(int i=0;i<d;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);if(a>b) swap(a,b);add(b,a,-c);}int res=spfa(0);if(res==-1) puts("-1");else{spfa(1);printf("%d",dist[n]==INF?-2:dist[n]);}return 0;
}

image-20240706170654003

4. 雇佣收银员

第一眼:

  • 感觉和区间会很像,一个时间段如果需要很多营业员,那么就让每个营业员的工作时间尽可能覆盖到这个区间
  • 输入处理比较麻烦(第二眼,实际上还好,就是变量表示需要思考一下

思考:

建边操作:

  • 用区间表示所需,采用前缀和来建立关系:

    • 某一时刻的营收员人数要大于等于这一时刻所需要的营收员人数

    • 上岗人数不能超过申请人数

  • 以时刻作为点

  • i时刻所需,i时刻申请,像是隐含的关系,就是一个人工作时长导致的区间内申请人数的变化仍然需要满足能够在某时刻大于等于所需的人数

  • 然后是某一时刻的申请人数也可以用前缀和来表示,于是可以x[i]的建边也可以用 s u m [ i ] − s u m [ i − 1 ] sum[i]-sum[i-1] sum[i]sum[i1]来表示

  • s u m [ i ] sum[i] sum[i] x [ i ] x[i] x[i] r [ i ] r[i] r[i] n u m [ i ] num[i] num[i]

  • 上岗人数约束关系如下:

    • 某一时刻的上岗人数 : s u m [ i ] − s u m [ i − 1 ] > = 0 sum[i]-sum[i-1]>=0 sum[i]sum[i1]>=0
    • 某一时刻的上岗和申请人数之间的关系: s u m [ i ] − s u m [ i − 1 ] ≤ n u m [ i ] sum[i]-sum[i-1]\le num[i] sum[i]sum[i1]num[i]
    • 某一时刻的所在的上岗人数,
      • [ 1 , 7 ] [1,7] [1,7]: s u m [ i ] + s u m [ 24 ] − s u m [ 24 − ( 7 − i ) ] > = r [ i ] sum[i]+sum[24]-sum[24-(7-i)]>=r[i] sum[i]+sum[24]sum[24(7i)]>=r[i] s u m [ i ] + s u m [ 24 ] − s u m [ 16 + i ] > = r [ i ] sum[i]+sum[24]-sum[16+i]>=r[i] sum[i]+sum[24]sum[16+i]>=r[i]
      • [ 8 , 24 ] [8,24] [8,24]: s u m [ i ] − s u m [ i − 8 ] > = r [ i ] sum[i]-sum[i-8]>=r[i] sum[i]sum[i8]>=r[i]
  • 转换成最短路模型如下:

    • s u m [ i ] > = s [ i − 1 ] sum[i]>=s[i-1] sum[i]>=s[i1]
    • s u m [ i − 1 ] > = s u m [ i ] − n u m [ i ] sum[i-1]>=sum[i]-num[i] sum[i1]>=sum[i]num[i]
    • s u m [ i ] > = s u m [ 16 + i ] − s u m [ 24 ] + r [ i ] sum[i]>=sum[16+i]-sum[24]+r[i] sum[i]>=sum[16+i]sum[24]+r[i]
    • s u m [ i ] > = r [ i ] + s u m [ i − 8 ] sum[i]>=r[i]+sum[i-8] sum[i]>=r[i]+sum[i8]
#include<bits/stdc++.h>using namespace std;
const int N=30,M=100;
int n,sum[N],r[N],num[N];
int h[N],e[M],ne[M],w[M],idx;
int cnt[N],st[N],q[M],d[N];void add(int a,int b,int c){e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}void build(int c){memset(h,-1,sizeof h);idx=0;for(int i=1;i<=24;i++){add(i-1,i,0);add(i,i-1,-num[i]);}for(int i=1;i<=7;i++) add(16+i,i,r[i]-c);for(int i=8;i<=24;i++) add(i-8,i,r[i]);add(0,24,c),add(24,0,-c);
}bool spfa(int s24){memset(d,-0x3f,sizeof d);memset(st,0,sizeof st);memset(cnt,0,sizeof cnt);build(s24);int hh=0,tt=1;d[0]=0;q[0]=0;while(hh!=tt){int t=q[hh++];if(hh==N) hh=0;st[t]=0;for(int i=h[t];i!=-1;i=ne[i]){int j=e[i];if(d[j]<d[t]+w[i]){d[j]=d[t]+w[i];cnt[j]=cnt[t]+1;if(cnt[j]>=25) return false;if(!st[j]){st[j]=1;q[tt++]=j;if(tt==N) tt=0;}}}}return true;
}signed main(){int t;cin>>t;while(t--){memset(num,0,sizeof num);for(int i=1;i<=24;i++){scanf("%d",r+i);}cin>>n;while(n--){int x;scanf("%d",&x);num[x+1]++;}int res=0;for(int i=0;i<=1000;i++){//res=spfa(i);if(spfa(i)){res=1;cout<<i<<endl;break;}}if(!res)puts("No Solution");}return 0;
}
2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
4
0
8
16
16

相关文章:

最短路算法——差分约束

差分约束 (1) 求不等式组的可行解 源点&#xff1a;从源点出发&#xff0c;一定可以走到所有的边求可行解步骤&#xff1a; 先将每个不等式 x i ≤ x j c x_i \le x_j c xi​≤xj​c,转化成一条从 s j s_j sj​走到 s i s_i si​&#xff0c;长度为 c k c_k ck​ 的一条边找…...

Log4j日志框架讲解(全面,详细)

目录 Log4j概述 log4j的架构&#xff08;组成&#xff09; Loggers Appenders Layouts 快速入门 依赖 java代码 日志的级别 log4j.properties 自定义Logger 总结&#xff1a; Log4j概述 Log4j是Apache下的一款开源的日志框架&#xff0c;通过在项目中使用 Log4J&…...

LeetCode 35, 242, 994

目录 35. 搜索插入位置题目链接标签思路代码 242. 有效的字母异位词题目链接标签思路代码 994. 腐烂的橘子题目链接标签思路代码 35. 搜索插入位置 题目链接 35. 搜索插入位置 标签 数组 二分查找 思路 本题与 704. 二分查找 十分相似&#xff0c;只不过本题在找不到 tar…...

ctfshow-web入门-文件包含(web87)巧用 php://filter 流绕过死亡函数的三种方法

目录 方法1&#xff1a;php://filter 流的 base64-decode 方法 方法2&#xff1a;通过 rot13 编码实现绕过 方法3&#xff1a;通过 strip_tags 函数去除 XML 标签 除了替换&#xff0c;新增 file_put_contents 函数&#xff0c;将会往 $file 里写入 <?php die(大佬别秀了…...

adb shell ps -T打印出来参数的含义,以及D,T,Z代表的状态含义是什么?

在Android系统中&#xff0c;使用adb shell ps命令可以查看当前系统中运行的进程信息。当你添加-T选项时&#xff08;注意&#xff0c;标准的ps命令在Android的adb shell中可能不直接支持-T选项&#xff0c;这通常与Linux中的ps命令略有不同&#xff09;&#xff0c;你可能是想…...

leetcode77组合——经典回溯算法

本文主要讲解组合的要点与细节&#xff0c;以及回溯算法的解题步骤&#xff0c;按照步骤思考更方便理解 c和java代码如下&#xff0c;末尾 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 具体要点&#xff1a; …...

springcloud-alibba之FeignClient

代码地址&#xff1a;springcloud系列: springcloud 组件分析拆解 1.FeignClient的集成 springboot版本&#xff1a;3.1.5 springcloud组件版本&#xff1a;2022.0.4 nacos客户端的版本&#xff1a;2.3.2 1.引pom 这里引入了nacos和feginclient的版本 <dependency>…...

三、docker配置阿里云镜像仓库并配置docker代理

一、配置阿里云镜像仓库 1. 登录阿里云官网&#xff0c;并登录 https://www.aliyun.com/ 2. 点击产品 - 容器 - 容器与镜像服务ACR - 管理控制台 - 镜像工具 - 镜像加速器 二、配置docker代理 #1. 创建docker相关的systemd文件 mkdir -p /etc/systemd/system/docker.servic…...

【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(十一)-git(3)

Git是目前最流行的版本控制系统之一&#xff0c;在现代软件开发中扮演着重要的角色。它能够有效地跟踪文件变化、协作开发&#xff0c;并存储项目的历史记录。本文的目的是向读者介绍Git的基本概念和工作原理&#xff0c;帮助初学者快速上手使用Git&#xff0c;并帮助有经验的开…...

全面解析 TypeScript 泛型的二三事

2024年了相信大家都已经在日常开发的过程中使用上了 TypeScript 了。TypeScript 增强了代码可靠性和可维护性&#xff0c;确保减少运行时错误并提高开发人员的工作效率。 TypeScript 通过类型声明 使得 javascript 拥有了强类型校验。而泛型的是类型声明中最重要的一环&#x…...

单/多线程--协程--异步爬虫

免责声明:本文仅做技术交流与学习... 目录 了解进程和线程 单个线程(主线程)在执行 多线程 线程池 协程(爬虫多用) 假异步:(同步) 真异步: 爬虫代码模版 异步-爬虫 同步效果--19秒 异步效果--7秒 了解进程和线程 ​ # --------------------> # ------> # …...

android pdf框架-11,查看图片

前10篇文章,9章关于pdf的,pdf解析后,里面也是有各种图片,于是利用pdf的view来展示图片,似乎也是个不错的想法. android手机中的图片查看功能,有的可以展示,有的不能.比如华为,荣耀对大体积的png是可以显示的,小米是不显示,只有缩略图. 一张png50m大,比如清明上河图,原图是tif…...

【CSS】深入浅出弹性布局

CSS的弹性布局&#xff08;Flexbox&#xff09;是一种用于在容器中沿着一维方向&#xff08;水平或垂直&#xff09;来布局、对齐和分配容器内项目空间的有效方式。它旨在提供一个更加有效的方式来布局、对齐和分配容器中项目的空间&#xff0c;即使它们的大小未知或是动态变化…...

医院挂号系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;患者管理&#xff0c;医生管理&#xff0c;专家信息管理&#xff0c;科室管理&#xff0c;预约信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;专家信息&#xff0…...

广州外贸建站模板

Yamal外贸独立站wordpress主题 绿色的亚马尔Yamal外贸独立站wordpress模板&#xff0c;适用于外贸公司建独立站的wordpress主题。 https://www.jianzhanpress.com/?p7066 赛斯科Sesko-W外贸建站WP主题 适合机械设备生产厂家出海做外贸官网的wordpress主题&#xff0c;红橙色…...

KDP数据分析实战:从0到1完成数据实时采集处理到可视化

智领云自主研发的开源轻量级Kubernetes数据平台&#xff0c;即Kubernetes Data Platform (简称KDP)&#xff0c;能够为用户提供在Kubernetes上的一站式云原生数据集成与开发平台。在最新的v1.1.0版本中&#xff0c;用户可借助 KDP 平台上开箱即用的 Airflow、AirByte、Flink、K…...

【人工智能】-- 智能机器人

个人主页&#xff1a;欢迎来到 Papicatch的博客 课设专栏 &#xff1a;学生成绩管理系统 专业知识专栏&#xff1a; 专业知识 文章目录 &#x1f349;引言 &#x1f349;机器人介绍 &#x1f348;机器人硬件 &#x1f34d;机械结构 &#x1f34d;传感器 &#x1f34d;控…...

Android广播机制

简介 某个网络的IP范围是192.168.0.XXX&#xff0c;子网 掩码是255.255.255.0&#xff0c;那么这个网络的广播地址就是192.168.0.255。广播数据包会被发送到同一 网络上的所有端口&#xff0c;这样在该网络中的每台主机都将会收到这条广播。为了便于进行系统级别的消息通知&…...

SQL FOREIGN KEY

SQL FOREIGN KEY 简介 SQL(Structured Query Language)是用于管理关系数据库管理系统(RDBMS)的标准编程语言。在SQL中,FOREIGN KEY是一个重要的概念,用于建立和维护数据库中不同表之间的关系。本文将详细介绍SQL FOREIGN KEY的概念、用途、以及如何在SQL中实现和使用FO…...

绘唐3最新版本哪里下载

绘唐3最新版本哪里下载 绘唐最新版本下载地址 推文视频创作设计是一种通过视频和文字的形式来进行推广的方式&#xff0c;可以通过一些专业的工具来进行制作。 以下是一些常用的小说推文视频创作设计工具&#xff1a; 视频剪辑软件&#xff1a;如Adobe Premiere Pro、Fina…...

[ES6] 箭头函数

JavaScript 是一种广泛使用的编程语言&#xff0c;随着其发展和演变&#xff0c;引入了很多新的特性来提高代码的可读性和开发效率。其中一个重要的特性就是 ES6&#xff08;ECMAScript 2015&#xff09;中引入的箭头函数&#xff08;Arrow Function&#xff09;。箭头函数不仅…...

BiLSTM模型实现

# 本段代码构建类BiLSTM, 完成初始化和网络结构的搭建 # 总共3层: 词嵌入层, 双向LSTM层, 全连接线性层 # 本段代码构建类BiLSTM, 完成初始化和网络结构的搭建 # 总共3层: 词嵌入层, 双向LSTM层, 全连接线性层 import torch import torch.nn as nn# 本函数实现将中文文本映射为…...

linux内核源码学习所需基础

1.面向对象的思想&#xff0c;尤其是oopc的实现方式。 2.设计模式。 这两点需要内核源码学习者不仅要会c和汇编&#xff0c;还要接触一门面向对象的语言&#xff0c;比如c&#xff0b;&#xff0b;/java/python等等任意一门都行&#xff0c;起码要了解面向对象的思想。 另外li…...

Java并发编程-AQS详解及案例实战(上篇)

文章目录 AQS概述AQS 的核心概念AQS 的工作原理AQS 的灵活性使用场景使用指南使用示例AQS的本质:为啥叫做异步队列同步器AQS的核心机制“异步队列”的含义“同步器”的含义总结加锁失败的时候如何借助AQS异步入队阻塞等待AQS的锁队列加锁失败时的处理流程异步入队的机制总结Ree…...

第11章 规划过程组(二)(11.8排列活动顺序)

第11章 规划过程组&#xff08;二&#xff09;11.8排列活动顺序&#xff0c;在第三版教材第391页&#xff1b; 文字图片音频方式 第一个知识点&#xff1a;主要输出 1、项目进度网络图 如图11-20 项目进度网络图示例 带有多个紧前活动的活动代表路径汇聚&#xff0c;而带有…...

DP学习——观察者模式

学而时习之&#xff0c;温故而知新。 敌人出招&#xff08;使用场景&#xff09; 多个对象依赖一个对象的状态改变&#xff0c;当业务中有这样的关系时你出什么招&#xff1f; 你出招 这个时候就要用观察者模式这招了&#xff01; 2个角色 分为啥主题和观察者角色。 我觉…...

如何利用GPT-4o生成有趣的梗图

文章目录 如何利用GPT-4o生成有趣的梗图一、引言二、使用GPT-4o生成梗图1. 提供主题2. 调用工具3. 获取图片实际案例输入输出 三、更多功能1. 创意和灵感2. 梗图知识 四、总结 如何利用GPT-4o生成有趣的梗图 梗图&#xff0c;作为互联网文化的一部分&#xff0c;已经成为了我们…...

深入理解 KVO

在 iOS 中&#xff0c;KVO&#xff08;Key-Value Observing&#xff09;是一个强大的观察机制&#xff0c;它的底层实现相对复杂。KVO 利用 Objective-C 的动态特性&#xff0c;为对象的属性提供观察能力。 KVO 的底层实现 1. 动态子类化 当一个对象的属性被添加观察者时&am…...

当需要对大量数据进行排序操作时,怎样优化内存使用和性能?

文章目录 一、选择合适的排序算法1. 快速排序2. 归并排序3. 堆排序 二、数据结构优化1. 使用索引2. 压缩数据3. 分块排序 三、外部排序1. 多路归并排序 四、利用多核和并行计算1. 多线程排序2. 使用并行流 五、性能调优技巧1. 避免不必要的内存复制2. 缓存友好性3. 基准测试和性…...

kubernetes集群部署:node节点部署和cri-docker运行时安装(四)

安装前准备 同《kubernetes集群部署&#xff1a;环境准备及master节点部署&#xff08;二&#xff09;》 安装cri-docker 在 Kubernetes 1.20 版本之前&#xff0c;Docker 是 Kubernetes 默认的容器运行时。然而&#xff0c;Kubernetes 社区决定在 Kubernetes 1.20 及以后的…...