【每日一题】【前缀和优化】【前/后缀最值】牛客练习赛139 B/C题 大卫的密码 (Hard Version) C++

牛客练习赛139 B题 大卫的密码 (Easy Version)
牛客练习赛139 C题 大卫的密码 (Hard Version)

大卫的密码

题目背景

牛客练习赛139

题目描述

给定一个 n × m n\times m n×m的网格图,我们使用 ( i , j ) (i,j) (i,j)表示网格中从上往下数第 i i i行和从左往右数第 j j j列的单元格。左上角为 ( 1 , 1 ) (1,1) (1,1),右下角为 ( n , m ) (n,m) (n,m),每个格子包含一个整数价值,使用 a i , j a_{i,j} ai,j表示。
一个光标在上面移动,从 ( s , 1 ) (s,1) (s,1)出发,每次可以向右或者向下移动,每个格子至多经过一次。当光标移动到 ( n , i ) ( 1 ≤ i ≤ m ) (n,i)(1\le i \le m) (n,i)(1im)格子,也就是最后一行的某个格子时,继续向下移动则会到达 ( 1 , i ) (1,i) (1,i)格子。大卫需要移动光标到达 ( t , m ) (t,m) (t,m),求最终大卫能获取的最大价值和。
注意本题的时间限制。本题数据量较大,我们建议您选取较快的读入方式。

输入格式

第一行输入四个整数 n , m , s , t ( 1 ≤ n , m ≤ 2 × 10 3 ; 1 ≤ s , t ≤ n ) n, m,s,t(1\le n ,m \le 2\times10^3;1\le s,t \le n) n,m,s,t(1n,m2×103;1s,tn)
注:简单版本的范围是 : 1 ≤ n , m ≤ 500 1\le n ,m \le 500 1n,m500
此后 n n n 行,第 i i i 行输入 m m m个整数 a i , 1 , a i , 2 , . . . , a i , m ( − 5 × 10 4 ≤ a i , j ≤ 5 × 10 4 ) a_{i,1},a_{i,2},...,a_{i,m}(-5\times 10^4\le a_{i,j} \le 5\times 10^4) ai,1,ai,2,...,ai,m(5×104ai,j5×104),表示一个格子的价值

输出格式

在一行上输出一个整数,表示大卫能获取的最大价值和。

样例 #1

样例输入 #1

3 3 1 2
1 2 3
4 5 6
7 8 9

样例输出 #1

38
说明

小红失去向上走的能力,消除 ( 1 , 3 ) (1,3) (1,3)处障碍,从起点到终点的最小步数为 6 6 6

样例 #2

样例输入 #2

5 5 1 5
6 10 4 10 6
-6 6 10 3 -1
-10 9 -6 -10 10
-3 8 4 5 6
-5 -8 2 4 8

样例输出 #2

100

做题要点

  1. 每次可以向右或者向下移动(说明不能往回走)
  2. 每个格子至多经过一次
  3. 时间给的是2s
  4. 到某一列的最后一行在往下就到该列的第一行

做题思路

先考虑简单版本

首先因为 1 ≤ n , m ≤ 500 1\le n ,m \le 500 1n,m500,所以哪怕是 O ( n 3 ) / O ( m × n 2 ) / O ( n × m 2 ) O(n^3) / O(m \times n^2) / O(n \times m^2) O(n3)/O(m×n2)/O(n×m2)都可以考虑

逆向思考

这里设 d p i , j dp_{i,j} dpi,j表示从起点走到 ( i , j ) (i,j) (i,j)点的大卫能获取的最大价值和。
从某一点 ( i , j ) (i,j) (i,j)考虑,那么答案一定是
d p i , j = { max ⁡ ( d p i , j − 1 , d p i − 1 , j ) + a i , j , ( i ≠ s , j ≠ 1 ) d p i , j = a i , j , ( i = s , j = 1 ) dp_{i,j} = \begin{cases} \max{(dp_{i,j-1},dp_{i-1,j})} + a_{i,j} , (i\neq s , j \neq 1) \\ dp_{i,j} = a_{i,j} ,(i = s , j = 1)\end{cases} dpi,j={max(dpi,j1,dpi1,j)+ai,j,(i=s,j=1)dpi,j=ai,j,(i=s,j=1)
加上记忆化搜索后dfs代码:

int dfs(int i,int j,int k){if(vis[i][j])return dp[i][j];vis[i][j] = true;if(i == s && j == 1)return dp[i][j] = a[i][j];int k1=-inf,k2=-inf;if(j != 1)k1=dfs(i,j_f(j),0);if(k < n-1)k2 = max(k2,dfs(i_f(i),j,k+1));return dp[i][j]=max(k1,k2) + a[i][j];
}

但是注意到某一列的最后一行在往下就到该列的第一行,所以就会出现一个环,导致递推式无法完全计算。
注意: d p i , j = max ⁡ ( d p i , j − 1 , d p i − 1 , j ) + a i , j dp_{i,j} = \max{(dp_{i,j-1},dp_{i-1,j})} + a_{i,j} dpi,j=max(dpi,j1,dpi1,j)+ai,j
那么 d p i , j dp_{i,j} dpi,j的答案依赖于 d p i , j − 1 dp_{i,j-1} dpi,j1 d p i − 1 , j dp_{i-1,j} dpi1,j,如果只关注后面的那个依赖关系
那么就会有
d p 2 , j dp_{2,j} dp2,j依赖于 d p 1 , j dp_{1,j} dp1,j
d p 1 , j dp_{1,j} dp1,j依赖于 d p m , j dp_{m,j} dpm,j
d p m , j dp_{m,j} dpm,j依赖于 d p m − 1 , j dp_{m-1,j} dpm1,j
d p m − 1 , j dp_{m-1,j} dpm1,j依赖于 d p m − 2 , j dp_{m-2,j} dpm2,j

d p 3 , j dp_{3,j} dp3,j依赖于 d p 2 , j dp_{2,j} dp2,j
最后就会发现 d p i , j dp_{i,j} dpi,j依赖于自己 d p i , j dp_{i,j} dpi,j( j ≠ 1 j\neq 1 j=1)。如果依赖符号用有向箭头连接成一个有向图,就会发现是一个环。所以此写法欠缺考虑。

注:如果不考虑记忆化搜索优化,会TLE

int dfs(int i,int j,int k){if(i == s && j == 1)return a[i][j];int k1=-inf,k2=-inf;if(j != 1)k1=dfs(i,j_f(j),0);if(k < n-1)k2 = max(k2,dfs(i_f(i),j,k+1));return max(k1,k2) + a[i][j];
}

正向思考

但刚刚的逆向思考中,会发现除了第一列的 d p i , 1 dp_{i,1} dpi,1都得到了答案,其他都是未知的或错解。
其根本原因是 ( s , 1 ) (s,1) (s,1)的点是起点, d p s , 1 dp_{s,1} dps,1不依赖于(其他)未知的量,更不依赖于本身。
至此第一列的答案都是可以由 d p s , 1 dp_{s,1} dps,1推出的定值
那假设从第一行第一列往第一行第二列走。并且设其 d p 1 , 2 = d p 1 , 1 + a 1 , 2 dp_{1,2} = dp_{1,1} + a_{1,2} dp1,2=dp1,1+a1,2。这样一来就达到了破环的效果,再用第一列的方法,一直向下推,可以推出其中一组 d p i , 2 dp_{i,2} dpi,2解。
同理如果从第二行第一列从第二行第二列走。并且设其 d p 2 , 2 = d p 2 , 1 + a 2 , 2 dp_{2,2} = dp_{2,1} + a_{2,2} dp2,2=dp2,1+a2,2。这样一来也就达到了破环的效果,再用第一列的方法,一直向下推,可以推出又一组 d p i , 2 dp_{i,2} dpi,2解。

同理如果从第 n n n行第一列从第 n n n行第二列走。并且设其 d p n , 2 = d p n , 1 + a n , 2 dp_{n,2} = dp_{n,1} + a_{n,2} dpn,2=dpn,1+an,2。这样一来也就达到了破环的效果,再用第一列的方法,一直向下推,可以推出又一组 d p i , 2 dp_{i,2} dpi,2解。

然后在 d p i , 2 dp_{i,2} dpi,2 解组( n n n组解) 中选择最大的值当作 d p i , 2 dp_{i,2} dpi,2的解即可
然后第二列的答案都是定值
以此类推直到最后一列
由此我们得到了第二个递推式:
f d p k , i , j fdp_{k,i,j} fdpk,i,j表示从第 k k k行第 j − 1 j-1 j1列往第 k k k行第 j j j列走后推出的一组解,并且设其 f d p k , k , j = d p k , j − 1 + a k , j fdp_{k,k,j} = dp_{k,j-1} + a_{k,j} fdpk,k,j=dpk,j1+ak,j
并且推出一组解的递推式为:
f d p k , i , j = f d p k , i − 1 , j + a i , j , ( i ≠ k ) fdp_{k,i,j} = fdp_{k,i-1,j} + a_{i,j} , (i \neq k) fdpk,i,j=fdpk,i1,j+ai,j,(i=k)
得到所以 m m m组解后,真正的答案选取最大的即可:
d p i , j = max ⁡ k = 1 n ( f d p k , i , j ) dp_{i,j} = \displaystyle\max_{k=1}^n{(fdp_{k,i,j})} dpi,j=k=1maxn(fdpk,i,j)
由第一列为定值推出第二列的值,可以将第二列看为定值推第三列,以此类推。
换句话说由第一列为定值推出第二列的值其实是枚举第二列的“起点”

#define RIP(i,j,k) for(int (i) = (j) ; (i) < (k) ; ++ i)
inline int f_i(int x){return x + 1 == n + 1 ? 1 : x + 1;}//往下
inline int i_f(int x){return x - 1 == 0 ? n : x - 1; }//往上
int ans[N][N];
bool vis[N][N]
RIP(j,1,m+1){for(int i = s ; !vis[i][j] ; i = f_i(i)){//枚举起点/转移行int ansi[N];//fdpvis[i][j] = true;ansi[i] = a[i][j] + ans[i][j-1];for(int k = f_i(i); k != i ; k = f_i(k)){ansi[k] = a[k][j] + ansi[i_f(k)];//fdp[i]  = fdp[i-1] + a[i][j]}//得到一组答案RIP(k,1,n+1)ans[k][j] = max(ans[k][j] , ansi[k]);//更新这一组答案if(j==1)break;//第一列的起点就一个}}

注意第一列的起点就一个!
总时间复杂度为 O ( m × n 2 ) O(m\times n^2) O(m×n2),在简单版本可以通过,但困难版本数据范围放大后就会TLE

如果要考虑通过困难版本就需要优化
将递推式 d p i , j = max ⁡ k = 1 n ( f d p k , i , j ) dp_{i,j} = \displaystyle\max_{k=1}^n{(fdp_{k,i,j})} dpi,j=k=1maxn(fdpk,i,j)展开就会有
d p i , j = max ⁡ k = 1 n d p k , j − 1 + ∑ o = k i a o , j dp_{i,j} = \displaystyle\max_{k=1}^n dp_{k,j-1} + \displaystyle\sum_{o=k}^i a_{o,j} dpi,j=k=1maxndpk,j1+o=kiao,j
其中 ∑ o = k i a o , j \displaystyle\sum_{o=k}^i a_{o,j} o=kiao,j表示从第 k k k行第 j j j列一直向下走直到第 i i i行第 j j j列的路径上的权值和。
那么重点是每次算这个路径权值和的时候是最里面的一层循环,并且还要求最大值。

for(int k = f_i(i); k != i ; k = f_i(k)){ansi[k] = a[k][j] + ansi[i_f(k)];//fdp[i]  = fdp[i-1] + a[i][j]}//得到一组答案RIP(k,1,n+1)ans[k][j] = max(ans[k][j] , ansi[k]);//更新这一组答案

这时候如果路径权值和能立马得到那么循环常数就可能会减少。如果把这一列数字单独拿出来当作一个数组 b i b_i bi,其实就是要求 ∑ i = l r b i \displaystyle\sum_{i=l}^r b_i i=lrbi
相当于多次要求区间和,我们可以考虑前缀和预处理优化。
p r e n = ∑ i = 1 n b n = ∑ i = 1 n a n , j ( j 为固定值 ) pre_n = \displaystyle\sum_{i=1}^n b_n = \displaystyle\sum_{i=1}^n a_{n,j} (j为固定值) pren=i=1nbn=i=1nan,j(j为固定值)
因为是一列一列考虑的所以j为固定值。相当于原本是:
p r e n , j = ∑ i = 1 n a n , j pre_{n,j} =\displaystyle\sum_{i=1}^n a_{n,j} pren,j=i=1nan,j “滚动化”
所以以下式子默认 p r e n = p r e n , j pre_n = pre_{n,j} pren=pren,j

接下来改写递推式,继续展开
d p i , j = max ⁡ d p k , j − 1 + { p r e i − p r e k − 1 , i ≥ k p r e n − p r e k − 1 + p r e i , i < k dp_{i,j} = \max dp_{k,j-1} + \begin{cases}pre_i - pre_{k-1} , i \ge k \\ pre_n - pre_{k-1} + pre_i , i \lt k \end{cases} dpi,j=maxdpk,j1+{preiprek1,ikprenprek1+prei,i<k

将预处理后的共同已知量提到 max ⁡ \max max外面得
d p i , j = p r e i + max ⁡ d p k , j − 1 + { − p r e k − 1 , i ≥ k p r e n − p r e k − 1 , i < k dp_{i,j} = pre_i + \max dp_{k,j-1} + \begin{cases} - pre_{k-1} , i \ge k \\ pre_n - pre_{k-1} , i \lt k \end{cases} dpi,j=prei+maxdpk,j1+{prek1,ikprenprek1,i<k

然而如果每个 i i i都枚举一遍 k k k时间复杂度依旧是 O ( m × n 2 ) O(m\times n^2) O(m×n2),这时候就需要预处理 k k k i i i的关系
假设 G i G_i Gi表示 max ⁡ d p k , j − 1 − p r e k − 1 , i ≥ k \max dp_{k,j-1} - pre_{k-1}, i \ge k maxdpk,j1prek1,ik
假设 L i L_i Li表示 max ⁡ d p k , j − 1 + p r e n − p r e k − 1 , i < k \max dp_{k,j-1} + pre_n - pre_{k-1} , i \lt k maxdpk,j1+prenprek1,i<k
那么原递推式就能写成
d p i , j = p r e i + max ⁡ ( G i , L i ) dp_{i,j} = pre_i + \max (G_i,L_i) dpi,j=prei+max(Gi,Li)
递推式就是只用枚举 i i i
那么问题就在于如何用线性时间复杂度预处理解出 G i G_i Gi L i L_i Li
从式子上发现 G i G_i Gi只与 k k k有关。也就是说
G 1 = d p 1 , j − 1 − p r e 0 G_{1} = dp_{1,j-1} - pre_{0} G1=dp1,j1pre0 ,(相当于 k k k只能选 { 1 } \set{1} {1})
G 2 = max ⁡ ( d p 1 , j − 1 − p r e 0 , d p 2 , j − 1 − p r e 1 ) = max ⁡ ( G 1 , d p 2 , j − 1 − p r e 1 ) G_{2} = \max(dp_{1,j-1} - pre_{0} , dp_{2,j-1} - pre_{1}) = \max(G_1,dp_{2,j-1} - pre_{1}) G2=max(dp1,j1pre0,dp2,j1pre1)=max(G1,dp2,j1pre1) ,(相当于 k k k只能选 { 1 , 2 } \set{1,2} {1,2})
同理 G 3 = max ⁡ ( G 2 , d p 3 , j − 1 − p r e 2 ) G_3 = \max{(G_2 , dp_{3,j-1} - pre_{2})} G3=max(G2,dp3,j1pre2)
以此类推 G i = max ⁡ ( G i − 1 , d p i , j − 1 − p r e i − 1 ) G_i = \max{(G_{i-1} , dp_{i,j-1} - pre_{i-1})} Gi=max(Gi1,dpi,j1prei1)

L i L_i Li只与 k k k有关,
L n = − i n f ( 无 ) L_n = -inf (无) Ln=inf() , (相当于 k k k没得选)
L n − 1 = d p n , j − 1 + p r e n − p r e n − 1 L_{n-1} = dp_{n,j-1} + pre_{n} - pre_{n-1} Ln1=dpn,j1+prenpren1,(相当于 k k k只能选 { n } \set{n} {n})
同理 L n − 2 = max ⁡ ( L n − 1 , d p n − 1 , j − 1 + p r e n − p r e n − 2 ) L_{n-2} = \max{(L_{n-1},dp_{n-1,j-1} + pre_{n} - pre_{n-2})} Ln2=max(Ln1,dpn1,j1+prenpren2)
以此类推 L i = max ⁡ ( L i + 1 , d p i + 1 , j − 1 + p r e n − p r e i ) L_i = \max{(L_{i+1} , dp_{i+1,j-1} + pre_n - pre_{i})} Li=max(Li+1,dpi+1,j1+prenprei)

RIP(j,1,m+1){int pre[N],L[N],G[N];RIP(i,0,n+1){pre[i] = 0;L[i] = G[i] = -inf;}RIP(i,1,n+1)pre[i] = pre[i-1] + a[i][j];RIP(i,1,n+1)G[i] = max(G[i-1],ans[i][j-1]-pre[i-1]);L[n] = -inf;L[n-1]=ans[n][j-1]+pre[n]-pre[n-1];rRIP(i,n-2,1)L[i]= max(L[i+1],ans[i+1][j-1] + pre[n] - pre[i]);RIP(i,1,n+1)ans[i][j] = pre[i] + max(L[i],G[i]);}

最后用上起点,和之前的思路一样。第一列只有一个起点,也就是说我们要保证
d p s , 0 = 0 且 d p s , 0 > > d p i , 0 ( i ≠ s ) dp_{s,0} = 0 且 dp_{s,0} >> dp_{i,0} (i\neq s) dps,0=0dps,0>>dpi,0(i=s)保证不能选到(有)从非起点行第0列转移到第一列的任意行的情况
所以设置 d p i , 0 = − i n f ( i ≠ s ) dp_{i,0} = -inf (i\neq s) dpi,0=inf(i=s)

RIP(i,1,n+1)ans[i][0]=-inf;ans[s][0]=0;

时间复杂度为 O ( m × n ) O(m\times n) O(m×n)

代码

#include <bits/stdc++.h>
#define int long long
#define RIP(i,j,k) for(int (i) = (j) ; (i) < (k) ; ++ i)
#define rRIP(i,j,k) for(int (i) = (j) ; (i) >= (k) ; -- i)
#define all(x) x.begin(),x.end()
#define endy {cout << "YES" << '\n'; return; }
#define endn {cout << "NO" << '\n'; return; }
#define endx(x) {cout << (x) << '\n'; return; }
#define conti(x) {cout << (x) << '\n';continue;}
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);
using namespace std;
using i128 = __int128;
using pii = pair<int,int>;
using tiii = tuple<int,int,int>;
using vi = vector<int>;
using vvi = vector<vi>;
using vii = vector<pii>;
using mii = map<int,int>;
const int N = 2e3+10;
const int mod = 1e9 + 7;
const int MID = 2e4+10;
const int inf = 0x3f3f3f3f3f3f3f3f;
int n = 1 , m  = 100 , s , t;int a[N][N];
int ans[N][N];
int read() {int x = 0, w = 1;char ch = 0;while (ch < '0' || ch > '9') {if (ch == '-') w = -1;ch = getchar();}while (ch >= '0' && ch <= '9') {x = x * 10 + (ch - '0');ch = getchar();}return x * w;
}
inline int f_j(int x){return x + 1 == m + 1 ? 1 : x + 1; }
inline int j_f(int x){return x - 1 == 0 ? m : x - 1; }
inline int f_i(int x){return x + 1 == n + 1 ? 1 : x + 1;}
inline int i_f(int x){return x - 1 == 0 ? n : x - 1; }
void solve(){n = read() , m = read() , s = read() , t = read();RIP(i,1,n+1)RIP(j,1,m+1){a[i][j] = read();ans[i][j] = -inf;}RIP(i,1,n+1)ans[i][0]=-inf;ans[s][0]=0;RIP(j,1,m+1){int pre[N],L[N],G[N];RIP(i,0,n+1){pre[i] = 0;L[i] = G[i] = -inf;}RIP(i,1,n+1)pre[i] = pre[i-1] + a[i][j];RIP(i,1,n+1)G[i] = max(G[i-1],ans[i][j-1]-pre[i-1]);L[n] = -inf;L[n-1]=ans[n][j-1]+pre[n]-pre[n-1];rRIP(i,n-2,1)L[i]= max(L[i+1],ans[i+1][j-1] + pre[n] - pre[i]);RIP(i,1,n+1)ans[i][j] = pre[i] + max(L[i],G[i]);}cout << ans[t][m];
}
signed main(){//IOS//int T;cin >> T;while(T--)solve();
}

简单版本

#include <bits/stdc++.h>
#define int long long
#define RIP(i,j,k) for(int (i) = (j) ; (i) < (k) ; ++ i)
#define rRIP(i,j,k) for(int (i) = (j) ; (i) >= (k) ; -- i)
#define all(x) x.begin(),x.end()
#define endy {cout << "YES" << '\n'; return; }
#define endn {cout << "NO" << '\n'; return; }
#define endx(x) {cout << (x) << '\n'; return; }
#define conti(x) {cout << (x) << '\n';continue;}
#define IOS std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);
using namespace std;
using i128 = __int128;
using pii = pair<int,int>;
using tiii = tuple<int,int,int>;
using vi = vector<int>;
using vvi = vector<vi>;
using vii = vector<pii>;
using mii = map<int,int>;
const int N = 2e3+10;
const int mod = 1e9 + 7;
const int MID = 2e4+10;
const int inf = 0x3f3f3f3f3f3f3f3f;
int n = 1 , m  = 100 , s , t;int a[N][N];
int ans[N][N];
bool vis[N][N];
int pre[N][N];
int read() {int x = 0, w = 1;char ch = 0;while (ch < '0' || ch > '9') {if (ch == '-') w = -1;ch = getchar();}while (ch >= '0' && ch <= '9') {x = x * 10 + (ch - '0');ch = getchar();}return x * w;
}
inline int f_j(int x){return x + 1 == m + 1 ? 1 : x + 1; }
inline int j_f(int x){return x - 1 == 0 ? m : x - 1; }
inline int f_i(int x){return x + 1 == n + 1 ? 1 : x + 1;}
inline int i_f(int x){return x - 1 == 0 ? n : x - 1; }
void solve(){n = read() , m = read() , s = read() , t = read();RIP(i,1,n+1)RIP(j,1,m+1){a[i][j] = read();ans[i][j] = -inf;}RIP(j,1,m+1)RIP(i,1,n+1)pre[i][j] = pre[i-1][j] + a[i-1][j];RIP(j,1,m+1){for(int i = s ; !vis[i][j] ; i = f_i(i)){int ansi[N];vis[i][j] = true;ansi[i] = a[i][j] + ans[i][j-1];for(int k = f_i(i); k != i ; k = f_i(k)){ansi[k] = a[k][j] + ansi[i_f(k)];}RIP(k,1,n+1)ans[k][j] = max(ans[k][j] , ansi[k]);if(j==1)break;}}cout << ans[t][m];
}
signed main(){//IOS//int T;cin >> T;while(T--)solve();
}

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

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

相关文章

文件夹图像批处理教程

前言 因为经常对图像要做数据清洗&#xff0c;又很费时间去重新写一个&#xff0c;我一直在想能不能写一个通用的脚本或者制作一个可视化的界面对文件夹图像做批量的修改图像大小、重命名、划分数据训练和验证集等等。这里我先介绍一下我因为写过的一些脚本&#xff0c;然后我…

【Unity实战笔记】第二十四 · 使用 SMB+Animator 实现基础战斗系统

转载请注明出处&#xff1a;&#x1f517;https://blog.csdn.net/weixin_44013533/article/details/146409453 作者&#xff1a;CSDN|Ringleader| 1 结构 1.1 状态机 1.2 SMB 2 代码实现 2.1 核心控制 Player_Base_SMB 继承 StateMachineBehaviour &#xff0c;控制变量初始…

Python虚拟环境再PyCharm中自由切换使用方法

Python开发中的环境隔离是必不可少的步骤,通过使用虚拟环境可以有效地管理不同项目间的依赖,避免包冲突和环境污染。虚拟环境是Python官方提供的一种独立运行环境,每个项目可以拥有自己单独的环境,不同项目之间的环境互不影响。在日常开发中,结合PyCharm这样强大的IDE进行…

大模型智能体入门扫盲——基于camel的概述

前言 本篇博客想带读者进行一个智能体入门扫盲&#xff0c;了解基础知识&#xff0c;为什么用camel呢&#xff0c;因为小洛发现它们文档对这种智能体的基本组件介绍得很全面深入。 基础概念 agent 一个典型的agent智能体包含三个核心部分&#xff1a; 感知模块&#xff1…

目标检测 RT-DETR(2023)详细解读

文章目录 主干网络&#xff1a;Encoder&#xff1a;不确定性最小Query选择Decoder网络&#xff1a; 将DETR扩展到实时场景&#xff0c;提高了模型的检测速度。网络架构分为三部分组成&#xff1a;主干网络、混合编码器、带有辅助预测头的变换器编码器。具体来说&#xff0c;先利…

DeepSeek 赋能数字农业:从智慧种植到产业升级的全链条革新

目录 一、数字农业的现状与挑战二、DeepSeek 技术解析2.1 DeepSeek 的技术原理与优势2.2 DeepSeek 在人工智能领域的地位与影响力 三、DeepSeek 在数字农业中的应用场景3.1 精准种植决策3.2 病虫害监测与防治3.3 智能灌溉与施肥管理3.4 农产品质量追溯与品牌建设 四、DeepSeek …

<uniapp><vuex><状态管理>在uniapp中,如何使用vuex实现数据共享与传递?

前言 本专栏是基于uniapp实现手机端各种小功能的程序&#xff0c;并且基于各种通讯协议如http、websocekt等&#xff0c;实现手机端作为客户端&#xff08;或者是手持机、PDA等&#xff09;&#xff0c;与服务端进行数据通讯的实例开发。 发文平台 CSDN 环境配置 系统&…

高速串行差分信号仿真分析及技术发展挑战续

7.3 3.125Gbps 差分串行信号设计实例仿真分析 7.3.1 设计用例说明 介绍完 Cadence 系统本身所具有的高速差分信号的仿真分析功能之后&#xff0c;我们以一个实例来说明 3.125Gbps 以下的高速差分系统的仿真分析方法。 在网上下载的设计文件“Booksi_Demo_Allegro160_Finishe…

【Golang】部分语法格式和规则

1、时间字符串和时间戳的相互转换 func main() {t1 : int64(1546926630) // 外部传入的时间戳&#xff08;秒为单位&#xff09;&#xff0c;必须为int64类型t2 : "2019-01-08 13:50:30" // 外部传入的时间字符串//时间转换的模板&#xff0c;golang里面只能是 &quo…

第十六章:数据治理之数据架构:数据模型和数据流转关系

本章我们说一下数据架构&#xff0c;说到数据架构&#xff0c;就很自然的想到企业架构、业务架构、软件架构&#xff0c;因为个人并没有对这些内容进行深入了解&#xff0c;所以这里不做比对是否有相似或者共通的地方&#xff0c;仅仅来说一下我理解的数据架构。 1、什么是架构…

Day126 | 灵神 | 二叉树 | 层数最深的叶子结点的和

Day126 | 灵神 | 二叉树 | 层数最深的叶子结点的和 1302.层数最深的叶子结点的和 1302. 层数最深叶子节点的和 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 这道题用层序遍历的思路比较好想&#xff0c;就把每层的都算一下&#xff0c;然后返回最后一层的和就…

PCIE 4.0 vs PCIE 5.0固态硬盘——区别、科普与选购场景全解析

随着数字内容和高性能计算需求的爆发&#xff0c;固态硬盘&#xff08;SSD&#xff09;已成为PC、游戏主机和工作站不可或缺的核心硬件。面对市面上层出不穷的新一代SSD产品&#xff0c;大家最常见的一个疑惑&#xff1a;**PCIe 4.0和PCIe 5.0固态硬盘&#xff0c;到底有啥区别…

vue pinia 独立维护,仓库统一导出

它允许您跨组件/页面共享状态 持久化 安装依赖pnpm i pinia-plugin-persistedstate 将插件添加到 pinia 实例上 pinia独立维护 统一导出 import { createPinia } from pinia import piniaPluginPersistedstate from pinia-plugin-persistedstateconst pinia creat…

Dify源码学习

文章目录 1 大模型基本原理1.1 model_context_tokens、max_tokens和prompt_tokens1.1.1 三者之间的关系1.1.2 总结对比 2 Dify源代码2.0 前后端代码跑起来【0】准备开发环境【1】下载代码【2】运行后端&#xff08;1&#xff09;Start the docker-compose stack&#xff08;2&a…

连接表、视图和存储过程

1. 视图 1.1. 视图的概念 视图&#xff08;View&#xff09;&#xff1a;虚拟表&#xff0c;本身不存储数据&#xff0c;而是封装了一个 SQL 查询的结果集。 用途&#xff1a; 只显示部分数据&#xff0c;提高数据访问的安全性。简化复杂查询&#xff0c;提高复用性和可维护…

微信小程序中,解决lottie动画在真机不显示的问题

api部分 export function getRainInfo() {return onlineRequest({url: /ball/recruit/getRainInfo,method: get}); }data存储json数据 data&#xff1a;{rainJson:{} }onLoad方法获取json数据 onLoad(options) {let that thisgetRainInfo().then((res)>{that.setData({r…

从加密到信任|密码重塑车路云一体化安全生态

目录 一、密码技术的核心支撑 二、典型应用案例 三、未来发展方向 总结 车路云系统涉及海量实时数据交互&#xff0c;包括车辆位置、传感器信息、用户身份等敏感数据。其安全风险呈现三大特征&#xff1a; 开放环境威胁&#xff1a;V2X&#xff08;车与万物互联&#xff0…

光谱相机在地质勘测中的应用

一、‌矿物识别与蚀变带分析‌ ‌光谱特征捕捉‌ 通过可见光至近红外&#xff08;400-1000nm&#xff09;的高光谱分辨率&#xff08;可达3.5nm&#xff09;&#xff0c;精确识别矿物的“光谱指纹”。例如&#xff1a; ‌铜矿‌&#xff1a;在400-500nm波段反射率显著低于围…

理论篇三:如何编写自定义的Webpack Loader或Plugin插件

在 Webpack 中,自定义 Loader 和 Plugin 是扩展构建能力的关键方式。以下是它们的实现方法和核心逻辑,通过代码示例和步骤拆解帮助你快速掌握。 一、自定义 Loader 1. Loader 的本质 作用:将非 JS 文件转换为 Webpack 能处理的模块。特点:纯函数,接收源文件内容,返回处理…

【算法】力扣体系分类

第一章 算法基础题型 1.1 排序算法题 1.1.1 冒泡排序相关题 冒泡排序是一种简单的排序算法&#xff0c;它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换&#xff0c…