数据结构与算法学习笔记----博弈论

# 数据结构与算法学习笔记----博弈论

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

ps⭐️包含了博弈论中的两种问题Nim游戏和SG函数,一共四道例题,给出了具体公式的证明过程。


Acwing 891. Nim游戏

[原题链接](891. Nim游戏 - AcWing题库)

给定 n n n堆石子,两位玩家轮流操作,每次操作可以从任意一堆石子中拿走任意数量的石子(可以拿完,但不能不拿),最后无法进行操作的人视为失败。

问如果两人都采用最优策略,先手是否必胜。

输入格式

第一行包含整数 n n n

第二行包含 n n n个数字,其中第 i i i个数字表示第 i i i个堆石子的数量。

输出格式

如果先手方必胜,则输出Yes

否则,输出No

数据范围

1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1n105,

1 ≤ 每堆石子数 ≤ 1 0 9 1 \le 每堆石子数 \le 10^9 1每堆石子数109

思路

我们先介绍以下今天这道题目的背景——公平组合游戏ICG。这种游戏有以下几个特征:

  1. 由两名玩家交替行动;
  2. 在游戏进程的任意时刻,可以执行的合法行动与轮到哪位玩家无关;
  3. 不能行动的玩家判负。

因此,类似围棋那种棋类游戏都不算公平组合游戏。

接下来进入Nim游戏的讲解,首先明白两个概念——先手必胜状态先手必败状态。其实很好理解:先手必胜状态意味着存在一种方法走到必败状态;而先手必败状态意味着无论怎么操作都不能走到一种先手必败状态。

然后我们就可以来看这个题目了,需要先介绍一个结论:

现在由 n n n堆石子,每堆石子有 a i a_i ai个,我们将所有的石子个数 a 1 ⊕ a 2 ⊕ ⋯ ⊕ a n a_1 \oplus a_2 \oplus \cdots \oplus a_n a1a2an异或起来,如果最后结果等于 0 0 0,那就是先手必败状态,否则就是先手必胜状态。

接下来我们来证明为什么这个结论是正确的:

首先,当我们进行到最后一步时,也就是无法进行任何一步操作时的情况 0 ⊕ 0 ⊕ ⋯ ⊕ 0 = 0 0 \oplus 0 \oplus \cdots \oplus 0 = 0 000=0,毫无疑问这是先手必败状态,符合上面的结论

第二种就是一般的情况, a 1 ⊕ a 2 ⊕ ⋯ ⊕ a n = x a_1 \oplus a_2 \oplus \cdots \oplus a_n = x a1a2an=x,所有石子个数异或后不等于 0 0 0,我们需要找到一种方式让其变成先手必败状态。我们需要的是找到 x x x的二进制表示中的最高的一位 1 1 1,假设其最高的一位 1 1 1在第 k k k位,那么一定存在一个 a i a_i ai,其第 k k k位是 1 1 1,这时就有 a i ⊕ x < a i a_i \oplus x < a_i aix<ai成立,这里举个例子解释一下:

ai     = 1 0 0 1 0 1 0 0
x  	   = 0 0 0 1 1 0 1 1
ai ^ x = 0 0 0 0 1 1 1 1

因为 x x x的最高位位置一定小于等于 a i a_i ai的最高位位置,因此上例子中我们所提到的第 k k k位对于 a i a_i ai来说是从左到右第 4 4 4位,那么高于这个位置的所有数都会被异或成 0 0 0,因此 a i ⊕ x < a i a_i \oplus x < a_i aix<ai成立。

那么我们就可以从 a i a_i ai这堆中拿走 a i − ( a i ⊕ x ) a_i - (a_i \oplus x) ai(aix)个石子,那么 a i a_i ai这堆最后剩下 a i − ( a i − ( a i ⊕ x ) ) = a i ⊕ x a_i - (a_i - (a_i \oplus x)) = a_i \oplus x ai(ai(aix))=aix个石子。

这时我们可以发现第二种一般的情况变成了
a 1 ⊕ a 2 ⋯ ⊕ ( a i ⊕ x ) ⋯ ⊕ a n = x ⊕ x = 0 a_1 \oplus a_2 \cdots \oplus (a_i \oplus x) \cdots \oplus a_n = x \oplus x = 0 a1a2(aix)an=xx=0
回到了第一种情况,也就是一定存在一个方式使剩下的所有石子个数异或起来为 0 0 0,那么为了说明我们上面蓝色结论正确,还有一步就是证明当所有石子个数异或起来为 0 0 0时,无论怎么拿,剩下的所有石子数目异或值不为 0 0 0

这里用反证法,假设我们可以从某一堆 a i a_i ai中拿走一定数量的石子使其变成 a i ′ a_i' ai并且所有石子个数异或起来仍然为 0 0 0,则有方程组
{ a 1 ⊕ a 2 ⋯ ⊕ a i ⊕ a n = 0 a 1 ⊕ a 2 ⋯ ⊕ a i ′ ⊕ a n = 0 \begin{cases} a_1 \oplus a_2 \cdots \oplus a_i \oplus a_n = 0 \\ a_1 \oplus a_2 \cdots \oplus a_i' \oplus a_n = 0 \end{cases} {a1a2aian=0a1a2aian=0
将两个方程左右两边分别异或起来有
a i ⊕ a i ′ = 0 a_i \oplus a_i' = 0 aiai=0
该等式成立的条件为 a i = a i ′ a_i = a_i' ai=ai,但是我们的假设是拿走了一定数量的石子,因此 a i ′ ≠ a i a_i' \neq a_i ai=ai,因此矛盾。

到这就可以写代码了,其实代码很短。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>using namespace std;int n;int main()
{cin >> n;int res= 0 ;while(n --){int x;cin >> x;res ^= x;}if(res) puts("Yes");else puts("No");return 0;
}

Acwing 892. 台阶-Nim游戏

[原题链接](892. 台阶-Nim游戏 - AcWing题库)

现在,有一个 n n n级台阶的楼梯,每级台阶上都有若干个石子,其中第 i i i级台阶上有 a i a_i ai个石子( i ≥ 1 i \ge 1 i1)。

两位玩家轮流操作,每次操作可以从任意一级台阶上拿若干个石子放到下一级台阶中(不能不拿)。

已经拿到地面上的石子不能再拿,最后无法进行操作的人视为失败。

问如果两人都采用最优策略,先手是否必胜。

输入格式

第一行包含整数 n n n

第二行包含 n n n个数字,其中第 i i i个数字表示第 i i i个级台阶上的石子数 q i q_i qi

输出格式

如果先手方必胜,则输出Yes

否则,输出No

数据范围

1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1n105,

1 ≤ a i ≤ 1 0 9 1 \le a_i \le 10^9 1ai109

思路

其实这题是上一题的稍微进阶版本,有了上一题的经验我们也知道这一题一定也存在所谓的先手必胜状态和先手必败状态。

题目中有一关键信息“每次都必须拿,已经拿到地面上的石子不能再拿,最后无法进行操作的人视为失败。”,那么我们对台阶进行编号,地面为第 0 0 0级,以此类推。

其实可以观察一下,对于偶数级台阶上的石子,假设只有三级 0 , 1 , 2 0,1,2 0,1,2,那么对于台阶 2 2 2上的石子一人拿了 x x x个到台阶 1 1 1后,另一人就可以将这 x x x个拿到台阶 0 0 0,而台阶 1 1 1上数量不变,也就是说偶数台阶上的石子操作不会影响大局。

而对于奇数台阶上的石子 a 1 , a 3 , ⋯ , a 2 n + 1 a_1,a_3,\cdots,a_{2n +1} a1,a3,,a2n+1,我们就可以看做是第一题中经典的Nim游戏了。

也就是 a 1 ⊕ a 3 ⋯ ⊕ a 2 n + 1 = x ≠ 0 a_1 \oplus a_3 \cdots \oplus a_{2n + 1} = x \neq 0 a1a3a2n+1=x=0时,先手必胜,否则先手必败。

同样我们分两种情况来看:

第一种情况 x ≠ 0 x \neq 0 x=0:

  1. 那么一定存在一种方式使某一堆 a i a_i ai变成 a i ⊕ x a_i \oplus x aix,从而所有奇数台阶石子异或值为 0 0 0,那么先手将 a i ⊕ x a_i \oplus x aix个石子往下拿之后,第二人有两种选择:

    • 一种是从偶数堆拿,那么不管它拿多少,我们都将他拿的数量再往下放,这样就不会打破奇数台阶的格局
    • 第二种是从奇数堆拿,那么就一定会打破奇数台阶的格局,我们继续像上面一样找到使所有奇数台阶数量异或为 0 0 0的拿法即可。

    也就是说,不管第二人怎么拿,我们都有石子拿,而第二人永远只能打破格局或者从偶数堆拿,最终没有石子拿的局面一定会被对手遇到,因此先手必胜。

那么对于第二种情况 x = 0 x = 0 x=0,我们根据上述分析已经可以得出结论了,这是先手必败的状态。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>using namespace std;int n;int main()
{cin >> n;int res = 0;for(int i = 1; i <= n; i ++){int x;cin >> x;if(i % 2) res ^= x;}if(res) puts("Yes");else puts("No");return 0;
}

Acwing 893. 集合-Nim游戏

[原题链接](893. 集合-Nim游戏 - AcWing题库)

给定 n n n堆石子以及一个由 k k k个不同正整数构成的数字集合 S S S

现在有两位玩家轮流操作,每次操作可以从任意一堆石子中拿取石子,每次拿取的石子数量必须包含于集合 S S S,最后无法进行操作的人视为失败。

问如果两人都采用最优策略,先手是否必胜。

输入格式

第一行包含整数 k k k,表示数字集合 S S S中数字的个数。

第二行包含 k k k个整数,其中第 i i i个整数表示数字集合 S S S中的第 i i i个数 s i s_i si

第三行包含整数 n n n

第四行包含 n n n个整数,其中第 i i i个整数表示第 i i i堆石子的数量 h i h_i hi

输出格式

如果先手方必胜,则输出Yes

否则,输出No

数据范围

1 ≤ n , k ≤ 100 1 \le n, k \le 100 1n,k100,

1 ≤ s i , h i ≤ 10000 1 \le s_i, h_i \le 10000 1si,hi10000

思路

从这一题开始我们介绍新一类博弈论题目,使用到了SG函数

首先我们先定义一个运算——Mex运算:找到一个集合中最小的不属于这个集合的自然数(最小非负整数)。比如有个集合 S = 1 , 2 , 3 S = {1, 2, 3} S=123,则有 M e x ( S ) = 0 Mex(S) = 0 Mex(S)=0

然后我们就可以引入SG函数了

对于游戏中的某个状态 G G G,其SG函数值 S G ( G ) SG(G) SG(G)定义为
S G ( G ) = m e x ( S G ( G ′ ) ∣ G ′ 是 G 的后继状态 ) SG(G) = mex(SG(G')| G'是G的后继状态) SG(G)=mex(SG(G)GG的后继状态)

他有两个关键性质:

  1. 终止状态的SG值为 0 0 0
  2. 如果 S G ( G ) = 0 SG(G) = 0 SG(G)=0,当前玩家处于必败态,否则为必胜态。

这里画一张图帮助理解,其实可以每种状态(或者说局面)可以看成一个结点,那么游戏中的所有局面可以看成一张有向图,如下图所示,每一个节点对应一种局面,每种局面与其能到达的后继局面之间由有向边连接。节点上的值为其SG值,如 S G = 3 SG = 3 SG=3的绿色节点,其能到达的局面有 0 , 1 , 2 0,1,2 0,1,2,因此其值为 3 3 3,其余节点以此类推,没有后继节点的局面SG值为 0 0 0。其实到这应该有一点头绪了,SG为 0 0 0的节点不能到达别的任何局面,也就是无法进行操作,因此是必败局面;而不为 0 0 0的节点一定可以到达某一个SG为 0 0 0的局面,因此为必胜局面。
在这里插入图片描述

那这里其实会有一个问题:必败定义为 0 0 0,必胜定义成 1 1 1不就行了嘛?为什么还有弄一个 m e x mex mex操作呢?

在讲这个问题之前,我们需要知道如果有多个子游戏,先手胜负状态的计算方法为 S G 总 = S G 1 ⊕ S G 2 ⊕ ⋯ ⊕ S G n SG_{总} = SG_1 \oplus SG_2 \oplus \cdots \oplus SG_n SG=SG1SG2SGn,同样的,当 S G 总 ≠ 0 SG_{总} \neq 0 SG=0时表示先手必胜,否则表示先手必败,证明的方法和第一题Nim游戏相同,只要将上面的石子数量 a i a_i ai改成 S G i SG_{i} SGi即可,大家可以回顾一下上面第一题

然后,我们确定简单定义为 0 0 0 1 1 1是可行的,但是只在一些简单的问题中可行,这样的做法会有局限性——无法区分不同状态的复杂性:在简单定义中,所有必胜态都被定义为1,所有必败态都被定义为0。但是很明显,这样会丢失一些信息,比如上图中的例子里, S G = 3 SG = 3 SG=3的节点可以为我们提供一个信息——他有多个后继节点,如果我们将其简单标记为1,则无法获得这一信息。

上图描述的一个游戏的情况,当我们需要考虑多个子游戏的时候,情况还会更加复杂,对于多个子游戏来说,我们最终的状态可以通过 S G 总 = S G 1 ⊕ S G 2 ⊕ ⋯ ⊕ S G n SG_{总} = SG_1 \oplus SG_2 \oplus \cdots \oplus SG_n SG=SG1SG2SGn得到。我们很容易就可以举出一个例子,比如两个游戏,如果其 S G SG SG值都简单记为1,那么异或值为0;如果一个为1,而另一个为2,异或值为3;很明显,虽然两个子游戏在两种标记方法中都满足 S G ≠ 0 SG \neq 0 SG=0,但是计算的结果却不同。

了解了这些就可以开始写代码了,比较复杂的地方是 S G SG SG函数的实现,其实类似于一个递归搜索的过程,至于最小的不存在的整数,可以使用集合来实现,具体的看代码吧

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <unordered_set>using namespace std;const int N = 10010;int n, m;
int f[N], s[N];int sg(int x)
{if(f[x] != -1) return f[x];unordered_set<int> S;for(int i = 0; i < n; i ++){int sum = s[i];if(x >= s[i]) S.insert(sg(x - sum));}for(int i = 0;; i ++){if(!S.count(i)){return f[x] = i;}}
}int main()
{cin >> n;for(int i = 0; i < n; i ++) cin >> s[i];memset(f, -1, sizeof f);cin >> m;int res = 0;for(int i = 0; i < m; i ++){int x;cin >> x;res ^= sg(x);}if(res) puts("Yes");else puts("No");return 0;}

Acwing 894. 拆分-Nim游戏

[原题链接](894. 拆分-Nim游戏 - AcWing题库)

给定 n n n堆石子,两位玩家轮流操作,每次操作可以取走其中的一堆石子,然后放入两堆规模更小的石子(新堆规模可以为0,且两个新堆的石子总数可以大于取走的那堆石子数),最后无法进行操作的人视为失败。)

问如果两人都采用最优策略,先手是否必胜。

输入格式

第一行包含整数 n n n

第二行包含 n n n个整数,其中第 i i i个整数表示第 i i i堆石子的数量 a i a_i ai

输出格式

如果先手方必胜,则输出Yes

否则,输出No

数据范围

1 ≤ n , a i ≤ 100 1 \le n, a_i \le 100 1n,ai100

思路

其实有了上面一题的经验,这题应该会简单一点了,首先要明确的就是这个游戏何时会结束:每次进行操作的时候虽然都会将一堆变为两堆,但是数值一定会减少,也就是说最后一定会有一堆操作完后变成了两堆0无法继续操作,这就是结束局面。

同样的,对于每一堆石子我们都可以计算 S G SG SG值,假设有一堆石子 a i a_i ai分为两堆 ( b 1 , b 2 ) (b_{1},b_{2}) (b1,b2),那么其分解后的 S G SG SG S G ( b 1 , b 2 ) = S G ( b 1 ) ⊕ S G ( b 2 ) SG(b_1,b_2) = SG(b_1) \oplus SG(b_2) SG(b1,b2)=SG(b1)SG(b2);不过我们需要注意的是可能会有多种操作方法,也就是说 a i a_i ai也可以分为两堆为 ( c 1 , c 2 ) (c_1,c_2) (c1,c2),只要满足题意即可,同样的会有 S G ( C 1 , C 2 ) = S G ( c 1 ) ⊕ S G ( c 2 ) SG(C_1,C_2) = SG(c_1) \oplus SG(c_2) SG(C1,C2)=SG(c1)SG(c2),那么对于 a i a_i ai来说,其 S G SG SG S G ( a i ) = S G ( b 1 , b 2 ) ⊕ S G ( c 1 , c 2 ) ⊕ ⋯ SG(a_i) = SG(b_1, b_2) \oplus SG(c_1, c_2) \oplus \cdots SG(ai)=SG(b1,b2)SG(c1,c2)

代码其实改一下上一题的就行了,不会很复杂。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <unordered_set>using namespace std;const int N = 110;int n ;
int f[N];int sg(int x)
{if(f[x] != -1) return f[x];unordered_set<int> S;for(int i = 0; i < x; i ++)for(int j = 0; j <= i; j ++)S.insert(sg(i) ^ sg(j));for(int i = 0; ; i ++)if(!S.count(i))return f[x] = i;
}int main()
{cin >> n;memset(f, -1, sizeof f);int res = 0;for(int i = 0; i < n; i ++){int x;cin >> x;res ^= sg(x);}if(res) puts("Yes");else puts("No");return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Yageo国巨的RC系列0402封装1%电阻库来了

工作使用Cadence多年&#xff0c;很多时候麻烦的就是整理BOM&#xff0c;因为设计原理图的时候图省事&#xff0c;可能只修改value值和封装。 但是厂家&#xff0c;规格型号&#xff0c;物料描述等属性需要在最后的时候一行一行的修改&#xff0c;繁琐又容易出错&#xff0c;过…

app专项测试(网络测试流程)

一、网络测试的一般流程 step1&#xff1a;首先要考虑网络正常的情况 ① 各个模块的功能正常可用 ② 页面元素/数据显示正常 step2&#xff1a;其次要考虑无网络的情况 ① APP各个功能在无网络情况下是否可用 ② APP各个页面之间切换是否正常 ③ 发送网络请求时是…

RFID隧道机:提升生产流水线效率与精准度

在当今制造业飞速发展的时代&#xff0c;生产流水线的效率与精准度成为企业竞争力的关键。传统的货物管理往往依赖于人工扫描和记录&#xff0c;效率低下且易出错&#xff0c;而RFID 隧道机的出现&#xff0c;为企业带来了智能化的管理体验&#xff0c;为生产流水线带来了从人工…

NSS-DAY2

Crypto [HNCTF 2022 Week1]A dictator 题目&#xff1a; from random import randint from secret import flagoffset randint(1,100) % 26 # print(offset)assert flag.startswith(NSSCTF{) assert all([ord(c) not in range(ord(A),ord(Z)) for c in flag[7:-1]])for cha…

systemctl配置httpd服务

一、环境介绍&#xff1a; Operating SystemopenEuler 22.03 (LTS-SP2)Kernel Linux 5.10.0-153.56.0.134.oe2203sp2.x86_64httpd versionhttpd-2.4.59ip address192.168.240.12/24 二、下载需要的软件包 yum install -y gcc gcc-c make apr apr-devel apr-util-devel pcre …

Redis bitmap应用

Redis bitmap应用 需求&#xff1a;存储用户今年已签到的天数&#xff0c;如在1月3日签到&#xff0c;则存 3 。。。以此类推 每秒300次请求压力测试 1、使用数据库存储 查询代码与时间 public List<Integer> selectSignRecord(long userId, Integer year) {if (year nu…

蓝桥杯之c++入门(六)【string(practice)】

目录 练习1&#xff1a;标题统计方法1&#xff1a;一次性读取整行字符&#xff0c;然后统计方法2&#xff1a;按照单词读取小提示&#xff1a; 练习2&#xff1a;石头剪子布练习3&#xff1a;密码翻译练习4&#xff1a;文字处理软件练习5&#xff1a;单词的长度练习6&#xff1…

uniapp访问django目录中的图片和视频,2025[最新]中间件访问方式

新建中间件, middleware.py 匹配,以/cover_image/ 开头的图片 匹配以/episode_video/ 开头的视频 imageSrc: http://192.168.110.148:8000/cover_image/12345/1738760890657_mmexport1738154397386.jpg, videoSrc: http://192.168.110.148:8000/episode_video/12345/compres…

gc buffer busy acquire导致的重大数据库性能故障

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 作者&#xff1a;IT邦德 中国DBA联盟(ACDU)成员&#xff0c;10余年DBA工作经验 Oracle、PostgreSQL ACE CSDN博客专家及B站知名UP主&#xff0c;全网粉丝10万 擅长主流Oracle、MySQL、PG、高斯…

[NKU]C++安装环境 VScode

bilibili安装教程 vscode 关于C/C的环境配置全站最简单易懂&#xff01;&#xff01;大学生及初学初学C/C进&#xff01;&#xff01;&#xff01;_哔哩哔哩_bilibili 1安装vscode和插件 汉化插件 ​ 2安装插件 2.1 C/C 2.2 C/C Compile run ​ 2.3 better C Syntax ​ 查看已…

DeepSeek-r1模型本地化部署最新教程

新的改变 DeepSeek 的搜索引擎基于深度学习算法&#xff0c;能够理解和分析大量的数据源&#xff08;如文本、图像、视频等&#xff09;&#xff0c;并结合用户的行为数据和偏好&#xff0c;提供个性化的搜索结果。 最近爆火的DeepSeek不用多说了&#xff0c;快来本地部署感受…

网络工程师 (20)计算机网络的概念

一、定义 计算机网络是指将地理位置不同、具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路及通信设备连接起来&#xff0c;在网络操作系统、网络管理软件及网络通信协议的管理和协调下&#xff0c;实现信息传递和资源共享的计算机通信系统。 二、组成 资源子网&…

支持向量机(一)

支持向量机是典型的二分类模型&#xff0c;以其模型简单、实现简单、效果卓越而著称。 一元支持向量机 我们通过一条中间线根据特征对样本实现分类&#xff0c;很明显&#xff1a;两个支持样本的差别越大&#xff0c;两个支持样本的分类效果就越好。 二元支持向量机 在实际生…

React 设计模式:实用指南

React 提供了众多出色的特性以及丰富的设计模式&#xff0c;用于简化开发流程。开发者能够借助 React 组件设计模式&#xff0c;降低开发时间以及编码的工作量。此外&#xff0c;这些模式让 React 开发者能够构建出成果更显著、性能更优越的各类应用程序。 本文将会为您介绍五…

vscode 如何通过Continue引入AI 助手deepseek

第一步&#xff1a; 在deepseek 官网上注册账号&#xff0c;得到APIKeys(deepseek官网地址) 创建属于自己的APIKey,然后复制这个key,(注意保存自己的key)! 第二步&#xff1a; 打开vscode,在插件市场安装Continue插件, 点击设置&#xff0c;添加deepseek模型&#xff0c;默认…

LPJ-GUESS模型入门(一)

一、模型简介 LPJ-GUESS是一个基于过程的动态植被陆地生态系统模型&#xff0c;专为区域或全球研究而设计。这种模型通常被称为动态全球植被模型&#xff08;DGVM&#xff09;。根据区域气候条件和大气二氧化碳浓度的数据&#xff0c;它可以预测地球主要气候带本土生态系统的结…

Windows本地部署DeepSeek-R1大模型并使用web界面远程交互

文章目录 前言1. 安装Ollama2. 安装DeepSeek-r1模型3. 安装图形化界面3.1 Windows系统安装Docker3.2 Docker部署Open WebUI3.3 添加Deepseek模型 4. 安装内网穿透工具5. 配置固定公网地址 前言 最近爆火的国产AI大模型Deepseek详细大家都不陌生&#xff0c;不过除了在手机上安…

MySQL时间类型相关总结(DATETIME, TIMESTAMP, DATE, TIME, YEAR)

MySQL时间类型相关总结(DATETIME, TIMESTAMP, DATE, TIME, YEAR) MySQL官方文档&#xff1a; https://dev.mysql.com/doc/refman/8.0/en/date-and-time-types.html 一. 对比&#xff1a; 在 MySQL 中&#xff0c;处理时间相关的数据类型主要有以下几种&#xff1a;DATE、TIME、…

Ubuntu部署Deepseek-R1模型(8b)

安装ubuntu系统 本机电脑系统ubuntu-20.04 #升级软件 sudo apt-get update#安装curl sudo apt-get install curl通过以上两条指令&#xff0c;完成了curl命令的安装。 安装ollama 打开Ollama官网 选择Linux&#xff0c; 给出如上图方框所示的一条指令 curl -fsSL https:…

【教程】docker升级镜像

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 自动升级 手动升级 无论哪种方式&#xff0c;最重要的是一定要通过-v参数做数据的持久化&#xff01; 自动升级 使用watchtower&#xff0c;可…