动态规划指南

news/2024/9/19 15:29:29/文章来源:https://www.cnblogs.com/hisy/p/18420621

线性 dp

线性 dp,就是指 dp 只有一维的 dp。因此,线性 dp 容易由 $\operatorname{O}(n)$ 的式子推出来。有时候,线性 dp 是需要结合其他的方法优化或者证明的。

例题

这一道题目可以很明显地推出式子,设 $dp_i$ 为以 $i$ 结尾的子序列最大长度。
$$\Large dp_i=\max_{j=1}^{i-1}(dp_j[a_i\ge a_j]+1)$$
那么,接下来,求出:
$$\Large\max_{i=1}^{n}(dp_i)$$
即可。

#include<bits/stdc++.h>
#define MAXN 5005
using namespace std;
int n,ans,a[MAXN],dp[MAXN];
int main(){scanf("%d",&n);for(int i=1;i<=n;++i){scanf("%d",&a[i]);}dp[n]=1;for(int i=n-1;i>=1;--i){int ans=0;for(int j=i+1;j<=n;++j){if(a[i]<=a[j]&&ans<dp[j]){ans=dp[j];}}dp[i]=1+ans;}for(int i=1;i<=n;++i){if(ans<dp[i]){ans=dp[i];}}printf("%d",ans);return 0;
}

背包 dp

01 背包

01 背包的题型是每一个物品都有价值 $w_i$ 和容量 $v_i$,你有一个总容量 $V$,你要从中选出若干个物品使得能够都装进背包然后价值总和最大。

很容易得出,将 $dp_{i,j}$ 表示为选到第 $i$ 个物品,剩余容量为 $j$ 的最大价值。且可以得出:
$$\Large dp_{i,j}=\max_{k=1}^{i-1}(dp_{k,j-v_{i}+w_{i}})$$
如果每一个 $dp_{i,j}$ 都继承上一个 $dp_{i-1,j}$,那么发现每一个 $i$ 都可以化成 $i$ 和 $i-1$ 的情况,所以可以用 $dp_{2,V}$ 来滚。

例题

01 背包板子题。

#include<bits/stdc++.h>
#define MAXN 101
#define MAXM 1001
using namespace std; 
int w[MAXN],v[MAXN],dp[MAXM];
int main(){int m,n;scanf("%d %d",&m,&n);for(int i=1;i<=n;++i){scanf("%d %d",&w[i],&v[i]);}for(int i=1;i<=n;++i){for(int j=m;j>=0;--j){if(j>=w[i]){dp[j]=max(dp[j-w[i]]+v[i],dp[j]);}}}printf("%d",dp[m]);return 0;
}

多重背包

多重背包是指每一个物品都能够选择若干次的背包。有时候,可以暴力拆成若干个 01 背包,但是有时候空间和时间都不支持。所以,我们需要优化。

二进制分组优化

这个是利用任何一个数都能够拆成 $\sum2_{s_i}$ 的形式。可以把个数 $c_i$ 拆成 $1,2,4\dots$ 的形式,这样就能拼凑出所有方案。

单调队列优化

朴素的转移方程是:
$$\Large dp_{i,j}=\max_{k=0}^{c_i}(dp_{i-1,j-k\times v_i}+k\times w_i)$$
我们掏出一个 $G_{x,y}=dp_{i,x\times v_i+y}$,一个 $H_{x,y}=dp_{i-1,x\times v_i+y}$,$x$ 表示选多少个,$y$ 表示剩余容量,则有:
$$\Large G_{x,y}=\max_{k=0}^{c_i}(H_{x-k,y}+k\times w_i)$$
我们再掏出一个 $S_{x,y}=H_{x,y}-x\times w_i$,则有:
$$\Large G_{x,y}=\max_{k=0}^{c_i}(S_{x-k,y})+x\times w_i$$
很明显可以使用单调队列进行维护。

例题

套用单调队列优化背包模板。

#include<bits/stdc++.h>
#define MAXN 40004
using namespace std; 
int dp[MAXN];
int main(){int n,m,ans=0;scanf("%d %d",&n,&m);while(n--){int w,v,sum;scanf("%d %d %d",&v,&w,&sum);if(!w){ans+=v*sum;continue;}sum=min(sum,m/w);for(int i=0;i<w;++i){deque<pair<int,int> > q;int part=(m-i)/w;for(int j=0;j<=part;++j){while(!q.empty()&&dp[i+j*w]-j*v>=q.back().second){q.pop_back();}q.push_back(make_pair(j,dp[i+j*w]-j*v));while(!q.empty()&&q.front().first<j-sum){q.pop_front();}dp[i+j*w]=max(dp[i+j*w],q.front().second+j*v);}}}printf("%d",ans+dp[m]);return 0;
}

无限背包

无限背包是指各种背包都有无限个,很明显可以有暴力式子:
$$\Large dp_{i,j}=\max_{k=0}^{i-1}(dp_{k,j-v_i\times k}+w_i\times k)$$
但是,可以发现,$dp_{i,j}$ 只需要通过 $dp_{i-1,j-v_i}$ 来转移即可。所以,基本上变成了 01 背包的代码。同样可以优化掉一维来优化。

例题

套用无限背包板子。

#include<bits/stdc++.h>
#define MAXN 10001
#define MAXM 10000001
using namespace std;
typedef long long ll;
ll v[MAXN],w[MAXN],dp[MAXM];
int main(){int m,n;scanf("%d %d",&m,&n);for(int i=1;i<=n;++i){scanf("%lld %lld",&w[i],&v[i]);}for(int i=1;i<=n;++i){for(int j=w[i];j<=m;++j){dp[j]=max(dp[j],dp[j-w[i]]+v[i]);}}printf("%lld",dp[m]);return 0;
}

混合背包

混合背包是指有一些物品能够拿 $1$ 次,有些物品能够拿 $c_i$ 次,有些物品能够拿无限次。这种背包只需要分类讨论每一种背包即可。

例题

套用混合背包板子。

#include<bits/stdc++.h>
#define MAXN 10001
#define MAXM 1001
using namespace std;
typedef long long ll;
int w[MAXN],v[MAXN],cnt[MAXN];
ll dp[MAXM];
inline ll time(){ll sh,ss,eh,es;scanf("%lld:%lld %lld:%lld",&sh,&ss,&eh,&es);ll s=sh*60+ss,e=eh*60+es;return e-s;
}
int main(){int m=time(),n;scanf("%d",&n);for(int i=1;i<=n;++i){scanf("%d %d %d",&v[i],&w[i],&cnt[i]);}for(int i=1;i<=n;++i){if(!cnt[i]){for(int j=v[i];j<=m;++j){dp[j]=max(dp[j],dp[j-v[i]]+w[i]);}}else{for(int j=1;j<=cnt[i];++j){for(int k=m;k>=j*v[i];--k){dp[k]=max(dp[k],dp[k-v[i]]+w[i]);}}}}printf("%lld",dp[m]);return 0;
} 

区间 dp

区间 dp 是指在 $dp_{l,r}$ 形式的 dp。这种 dp 是通过子区间来进行合并转移的,即 $dp_{l,r}=merge(dp_{l,k},dp_{k+1,r})$。这种思想是基于分治的。比如要想得到 $dp_{1,4}$,就得先得到 $dp_{1,1}$ 和 $dp_{2,4}$、$dp_{1,2}$ 和 $dp_{3,4}$ 或者 $dp_{1,3}$ 和 $dp_{4,4}$。

例题

记 $dp_{l,r}$ 为合并 $[l,r]$ 的最大值,然后可以套用 dp 公式。

#include<bits/stdc++.h>
#define MAXN 202
using namespace std;
int a[MAXN],dp[MAXN][MAXN];
int main(){int n;scanf("%d",&n);for(int i=1;i<=n;++i){scanf("%d",&a[i]);a[i+n]=a[i];}for(int len=2;len<=2*n;++len){for(int l=1,r=len;r<=2*n;++l,++r){for(int k=l;k<r;++k){dp[l][r]=max(dp[l][r],dp[l][k]+dp[k+1][r]+a[l]*a[r+1]*a[k+1]);}}}int ans=0;for(int i=1;i<=2*n;++i){ans=max(ans,dp[i][i+n-1]);}printf("%d",ans);return 0;
}

树形 dp

树形 dp 是通过树的顺序或者图的拓扑序来进行的 dp。通常来讲,子节点继承父节点的状态或者父节点继承诸多子节点的状态。

例题

很明显,看到这一条保证:

如果有一个编号为 $A$ 机器人指控或保护编号为 $B$ 的机器人,那么我们保证 $A<B$。

就可以推出这一个关系是一棵树。这时候,我们就可以使用树形 dp 来解。

很明显,当一条指控边出现,只可能是:

  • 狼人指控村民。
  • 村民指控狼人。
  • 村民指控村民。

当一条保护边出现,只可能是:

  • 狼人保护狼人。
  • 村民保护狼人。
  • 村民保护村民。

所以,利用这两点来建边就可以进行 dp 了。

具体可以使用记忆化搜索来实现。由于可能有森林的出现,所以定义一个根节点 $0$ 来连接其他点。从 $0$ 开始搜索,向下搜索,设 $dp_{i,j,k}(1\le i\le n,1\le j\le m,k\in{0,1})$ 为当前是节点 $i$,前面出现了 $j$ 个狼人,当前节点是否为狼人的方案数。

接下来,设 $u,v$ 表示 $u$ 有一条边通向 $v$,那么分类讨论:

  • 如果要计算为狼人的情况,并且为指控边,那么子节点必须为村民,则有 $dp_{u,j,1}=dp_{u,j-k,1}\times dp_{v,k,0}$。
  • 如果要计算为狼人的情况,并且为保护边,那么子节点必须为狼人,则有 $dp_{u,j,1}=dp_{u,j-k,1}\times dp_{v,k,1}$。
  • 如果要计算为村民的情况,并且为指控边,那么子节点可以为村民和狼人,需要加和,有 $dp_{u,j,0}=dp_{u,j-k,0}\times(dp_{v,k,0}+dp_{v,k,1})$。
  • 如果要计算为村民的情况,并且为保护边,那么子节点可以为村民和狼人,需要加和,有 $dp_{u,j,0}=dp_{u,j-k,0}\times(dp_{v,k,0}+dp_{v,k,1})$。
#include<bits/stdc++.h>
#define MAXN 202
#define MAXM 40004
#define MOD 1000000007
using namespace std;
typedef long long ll; 
struct node{int next,to;bool type;
}edge[MAXM<<2];
int n,m,k,cnt,head[MAXN];
bool vis[MAXN];
inline void addedge(int from,int to,bool type){edge[++cnt].to=to;edge[cnt].type=type;edge[cnt].next=head[from];head[from]=cnt;
} 
ll dp[MAXN][MAXN][2];
int size[MAXN];
bool in[MAXN];
void dfs(int u){size[u]=1;dp[u][0][0]=dp[u][1][1]=1ll;for(int i=head[u];i;i=edge[i].next){int v=edge[i].to;dfs(v);size[u]+=size[v];for(int j=size[u];j>=0;--j){ll ans1=0,ans0=0;for(int k=min(j,size[v]);k>=0;--k){if(edge[i].type){(ans1+=dp[u][j-k][1]*dp[v][k][0])%=MOD;}else{(ans1+=dp[u][j-k][1]*dp[v][k][1])%=MOD;}(ans0+=dp[u][j-k][0]*(dp[v][k][0]+dp[v][k][1]))%=MOD;}dp[u][j][0]=ans0;dp[u][j][1]=ans1;}}
}
int main(){scanf("%d %d %d",&n,&m,&k);while(k--){int u,v;char s[3]="";scanf("%s %d %d",s,&u,&v);if(*s=='A'){addedge(u,v,true);}else{addedge(u,v,false);}in[v]=true;}for(int i=1;i<=n;++i){if(!in[i]){addedge(0,i,true);}} dfs(0);printf("%lld",dp[0][m][0]);return 0;
}

状压 dp

状压 dp,就是把一些维度压缩成一个维度的 dp。比如,你需要记录 $1$ 到 $10$ 之内的布尔值,那么可以把 $10$ 位压缩成一个 int,也就是 $2^{10}$ 的空间。

有一些状压的基本操作:

  • (zip>>i)&1 表示查询 $zip$ 单位里面的第 $i$ 个元素的布尔值。
  • zip|(1<<(i-1)) 表示在 $zip$ 的基础上将第 $i$ 个元素值修改成 $1$。
  • zip-(1<<(i-1)) 表示在 $zip$ 的第 $i$ 的位置上是 $1$ 的基础上将 $i$ 修改成 $0$。
  • __builtin_popcount(zip) 表示统计 $zip$ 中有多少个 $1$。

状态压缩通常用于优化数位 dp。

例题

设 $dp_{zip,i}$ 表示走过的状态为 $zip$,下一个要走第 $i$ 个的状态。枚举每一个 $j$ 转移过来。如果 $zip$ 里面出现过 $j$,那就更新答案。

#include<bits/stdc++.h>
#define MAXN 21
using namespace std;
int n,dis[MAXN][MAXN],dp[1<<20|1][MAXN];
inline int read(){int res=0;char c=getchar();while(!isdigit(c)){c=getchar();}while(isdigit(c)){res=(res<<1)+(res<<3)+(c^48);c=getchar();}return res;
}
inline void write(int x){if(x>9){write(x/10);}putchar(x%10+'0');
}
int main(){n=read();for(register int i=1;i<=n;++i){for(register int j=1;j<=n;++j){dis[i][j]=read();}}memset(dp,0x3f,sizeof(dp));dp[1][1]=0;for(register int zip=1;zip<(1<<n);++zip){for(register int i=1;i<=n;++i){if(zip&(1<<(i-1))){continue;}for(register int j=1;j<=n;++j){if(!(zip&(1<<(j-1)))){continue;}dp[zip|(1<<(i-1))][i]=min(dp[zip|(1<<(i-1))][i],dp[zip][j]+dis[j][i]);}}}int ans=INT_MAX;for(register int i=2;i<=n;++i){ans=min(ans,dp[(1<<n)-1][i]+dis[i][1]);}write(ans);return 0;
}

优化

单调队列优化

在背包 dp 里面有提到过。原理是将 $dp$ 式子化成形如 $\max_{i=0}^{n}(dp)$ 类型的式子。

例题

很明显,初始 dp 式子是 $dp_{t,i,j}=\max(dp_{t-1,i,j},dp_{t-1,pre(i),pre(j)})$。其中,$pre$ 函数是该位置的上一个位置。在同一个方向上,可以使用单调队列优化。

#include<bits/stdc++.h>
#define MAXN 210
using namespace std;
int n,m,x,y,k,ans;
int dx[5]={0,-1,1,0,0};
int dy[5]={0,0,0,-1,1};
int dp[MAXN][MAXN];
char mp[MAXN][MAXN];
inline void move(int x,int y,int p,int l,int r){deque<pair<int,int> > q;for(int i=1;1<=x&&x<=n&&1<=y&&y<=m;++i,x+=dx[p],y+=dy[p]){if(mp[x][y]=='x'){q.clear();}else{while(!q.empty()&&q.back().first+i-q.back().second<dp[x][y]){q.pop_back();}q.push_back(make_pair(dp[x][y],i));while(!q.empty()&&q.back().second-q.front().second>r-l+1){q.pop_front();}ans=max(ans,dp[x][y]=q.front().first+i-q.front().second);}}
}
int main(){scanf("%d %d %d %d %d",&n,&m,&x,&y,&k);for(int i=1;i<=n;++i){scanf("%s",mp[i]+1);}memset(dp,0xf3,sizeof(dp));dp[x][y]=0;for(int i=1;i<=k;++i){int l,r,face; scanf("%d %d %d",&l,&r,&face);if(face==1){for(int j=1;j<=m;++j){move(n,j,face,l,r); }}else if(face==2){for(int j=1;j<=m;++j){move(1,j,face,l,r);}}else if(face==3){for(int j=1;j<=n;++j){move(j,m,face,l,r);}}else if(face==4){for(int j=1;j<=n;++j){move(j,1,face,l,r);}}}printf("%d",ans);return 0;
}

矩阵快速幂

矩阵快速幂是用于优化 dp 的。它通常能够优化到 $\log$ 级别的递推。

矩阵快速幂的本质是利用矩阵乘法的乘法结合律来用 $\log n$ 的时间复杂度来求出分矩阵,然后乘上原矩阵。

矩阵乘法的规则如下:

  • 定义 $x$ 为长度 $n,m$ 的矩阵,$y$ 为长度 $m,k$ 的矩阵,那么它们相乘的结果为长度为 $n,k$ 的矩阵 $res$。
  • $res_{i,j}=\sum_{k=1}^{m}x_{i,k}\times y_{k,j}$。

可以看出这一个式子似乎能够优化所有转移方程只带加法和乘法的 dp。但是,要证明两点:

  • 矩阵乘法不满足乘法交换律,因为交换后 $n$ 可能不等于 $k$。
  • 矩阵乘法满足结合律。因为 ${n,m}\times{m,k}\times{k,l}$,不管先算哪一个,要么得出 ${n,k}\times{k,l}={n,l}$,要么得出 ${n,m}\times{m,l}={n,l}$。

所以,矩阵乘法满足结合律。那么,矩阵乘法的递推式要视情况而定。

例题

这一道题目可以推出 dp 式子,设 $dp_{i,k}(1\le i\le n,k\in{0,1})$ 表示表示所有以 $i$ 为结尾的子串,选择相应的 $b$,满足 $k$ 对于相应子串是忠诚的,且 $k$ 的结尾与相应子串相同和不同的概率和。

设 $dp_{i,0/1}$ 表示所有以 $i$ 结尾的且长度在 $l$ 到 $r$ 之间的字串,选择相应的 $j$,满足 $j$ 对于相应字串是忠诚的,且 $j$ 的结尾相应字串相同和不同的概率和。另外设置辅助 dp 数组 $ldp_{i,0/1}$,$rdp_{i,0/1}$ 表示 $dp$ 数组,不同的是长度分别为 $1$ 到 $l-1$ 和 $r+1$ 到 $n$。递推式:
$$\Large dp_{i,0}=\frac{1}{2}\times(dp_{i-1,0}+dp_{i-1,1})+\frac{ldp_{i,0}}{2l}-\frac{rdp_{i,0}}{2r}$$

设 $g_{i,0/1}$ 表示到第 $i$ 个位置有多少个字串 $j$ 是忠诚的,有递推式 $g_{i,0}=g_{i-1,0}+g_{i-1,1}$,$g_{i,1}=g_{i-1,a_i}$。那么这一部分可以使用矩阵快速幂优化。之后,可以利用 $g$ 来求出 $ldp$ 和 $rdp$。

#include<bits/stdc++.h>
#define MOD 998244353
#define MAXN 5000005
#define getchar getchar_unlocked
#define putchar putchar_unlocked
using namespace std;
typedef long long ll;
typedef vector<vector<ll> > matrix;
matrix mtr1[2],mtr2[2],mtr3;
int n,l,r;
ll res1,res2,invl,invr,ans[MAXN],ldp[2][MAXN],rdp[2][MAXN],dp[2][MAXN];
inline ll read(void){ll res=0;char c=getchar();while(!isdigit(c)){c=getchar();}while(isdigit(c)){res=(res<<1)+(res<<3)+(c^'0');c=getchar();}return res;
}
void write(ll res){if(res>9){write(res/10);}putchar(res%10+'0');
}
inline matrix multi(const matrix &mtr1,const matrix &mtr2){matrix res;res.resize(2);res[0].resize(2);res[1].resize(2);res[0][0]=(mtr1[0][0]*mtr2[0][0]+mtr1[0][1]*mtr2[1][0])%MOD;res[1][0]=(mtr1[1][0]*mtr2[0][0]+mtr1[1][1]*mtr2[1][0])%MOD;res[0][1]=(mtr1[0][0]*mtr2[0][1]+mtr1[0][1]*mtr2[1][1])%MOD;res[1][1]=(mtr1[1][0]*mtr2[0][1]+mtr1[1][1]*mtr2[1][1])%MOD;return res;
}
inline ll power(ll x,ll y){ll res=1;while(y){if(y&1){(res*=x)%=MOD;};(x*=x)%=MOD;y>>=1;}return res;
}
inline ll inv(int number){return power(number,MOD-2);
}
const static ll invof2=inv(2);
int main(){mtr1[0].resize(2);mtr1[1].resize(2);mtr2[0].resize(2);mtr2[1].resize(2);for(register int i=0;i<2;++i){mtr1[0][i].resize(2);mtr1[1][i].resize(2);mtr2[0][i].resize(2);mtr2[1][i].resize(2);}mtr1[0][0][0]=mtr1[0][0][1]=mtr1[0][1][0]=1;mtr2[0][0][1]=mtr2[0][1][0]=1;mtr1[1][0][0]=mtr1[1][1][0]=mtr1[1][1][1]=1;mtr2[1][0][0]=mtr2[1][1][1]=1;mtr2[0][1][1]=mtr2[1][1][0]=MOD-1;n=read();l=read();r=read();invl=inv(power(2,l));invr=inv(power(2,r+1));res2=inv((1ll*(n*2-l-r+2)*(r-l+1)/2)%MOD);for(register int i=1;i<=n;++i){char c=getchar();while(c!='1'&&c!='0'){c=getchar();}ans[i]=c-'0';}mtr3.resize(2);mtr3[0].resize(2);mtr3[1].resize(2);mtr3[0][0]=mtr3[1][1]=1;mtr3[0][1]=mtr3[1][0]=0;for(register int i=1;i<l;++i){mtr3=multi(mtr3,mtr1[ans[i]]);}for(register int i=l;i<=n;++i){mtr3=multi(multi(mtr2[ans[i-l+1]],mtr3),mtr1[ans[i]]);ldp[0][i]=(mtr3[0][0]+mtr3[1][0])%MOD;ldp[1][i]=(mtr3[0][1]+mtr3[1][1])%MOD;}mtr3[0][0]=mtr3[1][1]=1;mtr3[0][1]=mtr3[1][0]=0;for(register int i=1;i<=r;++i){mtr3=multi(mtr3,mtr1[ans[i]]);}for(register int i=r+1;i<=n;++i){mtr3=multi(multi(mtr2[ans[i-r]],mtr3),mtr1[ans[i]]);rdp[0][i]=(mtr3[0][0]+mtr3[1][0])%MOD;rdp[1][i]=(mtr3[0][1]+mtr3[1][1])%MOD;}for(register int i=1;i<=n;++i){(dp[0][i]=(invof2*(dp[0][i-1]+dp[1][i-1])+invl*ldp[0][i]-invr*rdp[0][i])%MOD+MOD)%=MOD;(dp[1][i]=(invof2*(dp[ans[i]][i-1])+invl*ldp[1][i]-invr*rdp[1][i])%MOD+MOD)%=MOD;(res1+=(dp[0][i]+dp[1][i])%MOD)%=MOD;}write((res1*res2%MOD+MOD)%MOD);return 0;
}

决策单调性

三角形/四边形不等式

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

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

相关文章

易优eyoucms网站报错 \core\library\think\db\Connection.php 第 307 行左右,SQLSTATE[HY000] [1045]访问被拒,这样的情况要怎么处理啊

根据提供的错误信息 SQLSTATE[HY000] [1045] Access denied for user cs2021@localhost (using password: YES),这个错误表明数据库访问被拒绝了,通常是因为用户名或密码不正确导致的。 以下是几个可能的解决步骤:检查数据库连接配置:确认数据库连接配置文件中的用户名和密…

如何用Python将HTTP接口封装成可视化页面。

在软件行业中,经常会遇到有一些功能只能通过接口触发,没有页面。这样很不方便,。 我们这里,就是通过PyQt5实现,将接口的入参,封装成一个可视化的表单。将用户在表单中填写的数据,传给接口,接口再带参请求业务1.先看最终的效果,用户打开桌面应用后,只会出现下面的弹窗…

易优eyoucms网站php5.4版本,报错:Cant use method return value in write context

当你在使用 PHP 5.4 版本时遇到 “Cant use method return value in write context” 的错误,这通常是因为你在代码中错误地使用了方法返回值。这种错误通常发生在试图将方法返回值直接赋值给变量或用于其他上下文时。 解决方案 以下是一些常见的原因和解决方法: 1. 检查代码…

易优eyoucms网站报错 /core/library/think/db/Connection.php 第 389 行左右,如何解决?

SQLSTATE[42S22]: Column not found: 1054 Unknown column groupid in where clause 遇到“SQLSTATE[42S22]: Column not found: 1054 Unknown column groupid in where clause”这类错误,通常是因为数据库表结构与代码中的查询不匹配。具体来说,可能是数据库表中缺少某个列(…

【HFSS】HFSS绘制梯形走线的5种方法

使用HFSS仿真PCB走线,需要对走线进行建模,但是由于PCB制造过程中的蚀刻导致走线截面不是理想的矩形,而是接近梯形。为了使仿真尽量精确,需要将PCB走线截面绘制成梯形。下面介绍几种绘制梯形走线的方法。 方法一:修改line参数直接生成梯形 1)画一条线100mil,右侧窗口选中…

汇总区间

给定一个有序的list, 需要根据数据的连续性进行区间的汇总实例如下: 解决方法:设置左右指针,固定左指针,当右指针对应的数+1=右指针+1对应的数 and 右指针不要越界,就移动右指针,直到跳出while,并更新左指针=右指针+1class Solution(object):def summaryRanges(self, n…

element-plus 如何修改el-table 滚动条高度,el-table滚动条放置在表格外面

element-plus el-table 滚动条高度, el-scrollbar,滚动条放置在表格外面,滚动条放置在表格外部先上效果图: 实现方式,自定义全局的element样式如下:/** * 表格滚动条 */// 横向滚动条高度 $scrollbarheight: 15px; .el-scrollbar {//偏移.el-scrollbar__bar{bottom: 1p…

MindSearch 快速部署

基础任务(完成此任务即完成闯关)按照教程,将 MindSearch 部署到 HuggingFace 并美化 Gradio 的界面,并提供截图和 Hugging Face 的Space的链接。MindSearch 部署到Github Codespace 和 Hugging Face Space 和原有的CPU版本相比区别是把internstudio换成了github codespace。…

小程序隐私合规自查指南

一 背景:小程序作为一种轻量级应用,广泛应用于各大互联网平台。工信部通报2022年第5批侵害用户权益名单中首次出现8款违规小程序。各监管单位对“小程序”违规收集个人信息监控手段和监控力度不断加强。 工信部APP违法违规通报 上海市委网信办查处违规小程序二、小程序隐私合…

Jmeter的简单使用一:http请求

1、创建线程组setUp和tearDown线程组类似测试用例的测试开始之前执行某些初始化操作,如环境准备、数据库连接和释放数据库连接2、设置线程组Ramp-Up时间(以秒为单位)是指从开始到所有线程都达到活动状态的时间。例如,如果你设置了10个线程,并且Ramp-Up时间为20秒,那么JMe…

Flags

Flags是位字段的序列,当其中任何一个位不为零且广播可连接时广播包中应包含flags. 否则,flags可以被忽略。flags只能包含在广播包中,扫描响应包中不能包含flags。flags的作用是在广播包中加入如下标志:有限可发现模式;一般可发现模式;不支持BR/EDR;设备同时支持LE和BR/E…

Oracle 19c OCP 认证考试 082 题库(第23题)- 2024年修正版

【优技教育】Oracle 19c OCP 082题库(Q 23题)- 2024年修正版 考试科目:1Z0-082 考试题量:90 通过分数:60% 考试时间:150min 本文为(CUUG 原创)整理并解析,转发请注明出处,禁止抄袭及未经注明出处的转载。 原文地址:http://www.cuug.com/index.php?s=/home/article/deta…