$DP$选讲

直接上题吧

放个题单

[各省省选DP](https://www.luogu.com.cn/training/151079)

$P5322[BJOI2019]$排兵布阵

一眼题,考虑$dp[i][j]$表示已经确定前$i$个的选的数量$j$的最大收益,考虑怎么转移

直接转移这一维和上一维的数量,枚举复杂度$O(n\times m^2)$

那么显然的是直接枚举有很多状态无用,那么有用的决策点只有$k$个

那么直接枚举决策点,那么非决策点必定不优,显然的是就是你在两个决策点之间

花费是无用的,那么复杂度变为$O(n\times m\times k)$

#include<bits/stdc++.h>
#define MAXM 20005
#define MAXN 150
using namespace std;
inline int rd(){
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int jc[MAXN][MAXN];
int a,s,n,m,val[MAXN][MAXN],dp[2][MAXM];
int main()
{
cin>>s>>n>>m;
for(int i=1;i<=s;i++)
{
for(int j=1;j<=n;j++)
{
a=rd();
jc[j][i]=a;
}
}
for(int i=1;i<=n;i++)
{
sort(jc[i]+1,jc[i]+1+s);
for(int j=1;j<=s;j++)
{
val[i][j]=2*jc[i][j]+1;
}
}
for(int i=1;i<=n;i++)
{
int now=(i&1),pre=(now^1);
// memset(dp[now],0xcf,sizeof(dp[now]));
for(int k=0;k<=s;k++)
{
for(int j=0;j<=m;j++)
{
if(j<val[i][k])
{
dp[now][j]=max(dp[now][j],dp[pre][j]);
}
else
{
dp[now][j]=max(dp[now][j],max(dp[pre][j],dp[pre][j-val[i][k]]+i*k));
}
}
}
// for(int j=0;j<=m;j++)
// {
// cout<<dp[now][j]<<" ";
// }
// cout<<endl;
}
cout<<dp[n&1][m]<<endl;
}
/*
1 3 10
2 2 6 ./a.exe<a.in>a.out 2 3 10
2 2 6
0 0 0
*/

$BJOI[2019]$奥术神杖

上来第一眼没有思路,由于直接$DP$显然不好求解,而且这个记录贡献的方式很生草

先考虑如果确定了最后状态,那么答案怎么求$?$

$\sqrt{\Pi_{i=1}^{|s|}v[i]}^{|s|}$

就是把所有出现的咒语乘起来,对总次数开根号

套路,取$log$

那么式子变为

$Ans=log(\sqrt{\Pi_{i=1}^{|s|}v[i]}^{|s|})$

$Ans=log((\Pi_{i=1}^{|s|}v[i])^\frac{1}{|s|})$

$Ans=\frac{1}{|s|}log(\Pi_{i=1}^{|s|}v[i])$

$Ans=\frac{1}{|s|}\sum_{i=1}^{|s|}log(v[i])$

(不得不说$log$乘法转加法真的很好用)

再次发现,这个东西无法直接转移

以我的理解是这个不满足最优子问题结构,无法设计一个好的状态去转移,就是说你用这个状态无法能去转移

就是无法设计一个状态去转移,就是即使你设计$dp[i][j]$也无法完整考虑个数这个问题

而且你次数与次数之间没办法转移,即使你当前保证是当前乘积最大值,也不能开完之后还是最大值

或许你可以换个状态,$dp[i][j]$表示确定了$i$位,匹配$j$个的乘积最大值

发现没办法转移,你需要确定这一位,然后并不知道匹配了多少个

你又说,再多设一维,并且把$dp$设在$AC$自动机上

$dp[i][j][k]$表示目前确定了$i$位,已经匹配了$j$个,目前在$AC$自动机的第$k$个节点的最大乘积

大概的转移方式就是$dp[i+1][j+val[y]][y]=dp[i][j][k]$

结果发现这个可以转移。。。但是你看看这个复杂度就很不友好

在极限数据下的话$dp$状态数是$O(n\times n^2\times cnt)$

分别是$n$个位置,一共所有可能匹配数目$n^2$,和$AC$自动机的节点数

那么用一个很好的套路,对于这种样子带着小数的$dp$,显然可以想到分数规划

然后判断是否合法吧

那么就是这个样子$\frac{1}{|s|}\sum_{i=1}^{|s|}log(v[i])>=mid$

$\sum_{i=1}^{|s|}(log(v[i])-mid)>=0$

那么对于每个贡献$-=mid$,然后转移这个式子的最大值,判断是否大于$0$

发现一个很有意思的事情,这个式子不存在那个烦人的开根号,只需要累和就好了

然后这个也不必关心匹配了几个,只需要一直累加就好了,貌似就解决了

大概重新透彻了分数规划的意义,就是某些状态转移需要和数量或其他有关联

那么就分数规划化简式子,换一种统计方法得到最优

也就是这道题,直接转移不好写,化简完式子之后发现只需要发现有了一个新的匹配直接加上新的匹配的贡献就好了

这个也很好的解决了,式子本身含义也是所有出现的贡献累加起来

这个式子的最大值很好转移

设$dp[i][j]$表示目前已经确定了$i$位,转移到了第$j$个节点的这个式子的最大值

那么转移的话也很简单了

而且这样转移和$AC$自动机匹配性质一样,显然可以得到所有的状态,而且贡献正确

#include<bits/stdc++.h>
#define INF 2147473647
#define MAXN 2005
using namespace std;
const double eps=1e-5;
int tr[MAXN][15],End[MAXN],fail[MAXN],cnt,n;
int zy[MAXN][MAXN][2];
double F[MAXN][MAXN],val[MAXN];
char T[MAXN];
void Insert(char *s,double w)
{
int now=0;
for(int i=1;s[i];i++)
{
if(!tr[now][s[i]-'0'])
{
tr[now][s[i]-'0']=++cnt;
}
now=tr[now][s[i]-'0'];
}
End[now]++;
val[now]+=w;
}
void Get_fail()
{
queue<int>q;
int now=0;
for(int i=0;i<10;i++)
{
if(tr[now][i])
{
q.push(tr[now][i]);
}
}
while(!q.empty())
{
int now=q.front();
End[now]+=End[fail[now]];
val[now]+=val[fail[now]];
q.pop();
for(int i=0;i<10;i++)
{
if(tr[now][i])
{
fail[tr[now][i]]=tr[fail[now]][i];
q.push(tr[now][i]);
}
else
{
tr[now][i]=tr[fail[now]][i];
}
}
}
}
char Ans[MAXN];
double dp(double v)
{
for(int i=0;i<=cnt;i++)
{
val[i]-=End[i]*v;
}
for(int i=0;i<=n;i++)
{
for(int j=0;j<=cnt;j++)
{
F[i][j]=-1e100;
}
}
F[0][0]=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<=cnt;j++)
{
if(F[i][j]>-1e99)
{
for(int k=0;k<10;k++)
{
if(T[i]!='.'&&T[i]!=k+'0') continue;
int y=tr[j][k];
if(F[i+1][y]<F[i][j]+val[y])
{
F[i+1][y]=F[i][j]+val[y];
zy[i+1][y][0]=j;
zy[i+1][y][1]=k;
//¼ÇÂ¼×ªÒÆµã
}
}
}
}
}
for(int i=0;i<=cnt;i++)
{
val[i]+=End[i]*v;
}
int pos=0;
for(int i=1;i<=cnt;i++)
{
if(F[n][i]>F[n][pos]) pos=i;
}
for(int i=n,now=pos;i;i--)
{
Ans[i]=zy[i][now][1]+'0';
now=zy[i][now][0];
}
return F[n][pos];
}
int m,v;
char s[MAXN];
int main()
{
cin>>n>>m;
scanf("%s",T);
for(int i=1;i<=m;i++)
{
scanf("%s",s+1);
scanf("%d",&v);
Insert(s,log(v));
}
Get_fail();
double l=0,r=log(INF),res=0;
while(r-l>eps)
{
double mid=(l+r)/2.0;
if(dp(mid)>0) res=mid,l=mid;
else r=mid;
}
dp(res);
printf("%s",Ans+1);
}

$ZJOI2019$线段树

也不知道$ZJ$出题人怎么想的,一天三道题都是$DP$

这个还是比较简单了

一个很显然的套路,就是可以考虑换一种枚举方式统计贡献

这个不是每个线段树有多少节点被打标记吗

转化思路为这个节点被多少个线段树打标记去累和

那么$dp[i][j]$表示第$i$个节点在前$j$次复制后有多少个被打标记

那么转移就很显然了

//真是不知道能在线段树上跑DP的出题人怎么想
//首先,这个东西肯定不能每次都重开线段树
//那么在一棵线段树上转移
//dp[now][i]当前节点在前i次操作覆盖了几次
//那么这么显然可以直接转移吧
//我们相当于知道了前面所有线段树的这个点状态
//那么由于转移是独立的,那么该咋搞咋搞
//我在想这个东西貌似不太对,就是说会不会出现
//貌似没有影响,因为不会出现标记为2
//我貌似又忘记一个东西叫,贡献独立
//既然整体不好搞,那我们很显然可以单独计算每一个贡献累加
#include<bits/stdc++.h>
#define int long long
#define mod 998244353
#define MAXN 200005
#define ls (now<<1)
#define rs ((now<<1)|1)
using namespace std;
struct node
{
int l,r,sum;
}tr[MAXN<<2];
int f[MAXN<<2],g[MAXN<<2],tf[MAXN<<2],tg[MAXN<<2],cnt;
void build(int now,int l,int r)
{
tr[now].l=l,tr[now].r=r;
f[now]=0;
g[now]=1;
tf[now]=1;
tg[now]=1;
if(l==r) return ;
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
}
void pdTf(int now,int x)
{
(tr[now].sum*=x)%=mod;
(tf[now]*=x)%=mod;
(f[now]*=x)%=mod;
}
void pdTg(int now,int x)
{
(tg[now]*=x)%=mod;
(g[now]*=x)%=mod;
}
void pd(int now)
{
if(tf[now]!=1)
{
pdTf(ls,tf[now]);
pdTf(rs,tf[now]);
tf[now]=1;
}
if(tg[now]!=1)
{
pdTg(ls,tg[now]);
pdTg(rs,tg[now]);
tg[now]=1;
}
}
void push_up(int now)
{
tr[now].sum=(f[now]+tr[ls].sum+tr[rs].sum)%mod;
}
void change(int now,int l,int r)
{
pd(now);
if(tr[now].l==l&&tr[now].r==r)
{
f[now]=(f[now]+cnt)%mod;
g[now]=g[now]%mod;
pdTf(ls,2);
pdTf(rs,2);
}
else
{
int mid=(tr[now].l+tr[now].r)>>1;
g[now]=(g[now]+cnt)%mod;
if(r<=mid)
{
change(ls,l,r);
pd(rs);
f[rs]=(f[rs]+cnt+mod-g[rs])%mod;
g[rs]=(g[rs]+g[rs])%mod;
pdTf(rs<<1,2);pdTg(rs<<1,2);
pdTf(rs<<1|1,2);pdTg(rs<<1|1,2);
push_up(rs);
}
else if(l>mid)
{
change(rs,l,r);
pd(ls);
f[ls]=(f[ls]+cnt+mod-g[ls])%mod;
g[ls]=(g[ls]+g[ls])%mod;
pdTf(ls<<1,2);pdTg(ls<<1,2);
pdTf(ls<<1|1,2);pdTg(ls<<1|1,2);
push_up(ls);
}
else
{
change(ls,l,mid);
change(rs,mid+1,r);
}
}
push_up(now);
}
int n,m,opt,l,r;
signed main()
{
cin>>n>>m;
build(1,1,n);
cnt=1;
for(int i=1;i<=m;i++)
{
cin>>opt;
if(opt==1)
{
cin>>l>>r;
change(1,l,r);
cnt=(cnt+cnt)%mod;
}
if(opt==2)
{
cout<<tr[1].sum<<endl;
}
}
}

十二省联考2019皮配

简化题意就是每个人有两个性质,每个人有一个体积,还有一些人有性质限制,每种性质有体积限制,最后让求所有的方案数,同一个城市的第一个性质必须相同

那么就可以转化为,每个人是豆子,同一个城市里的是豆荚,同一豆荚里面的颜色相同,最后每种性状有重量限制,问最后的方案数

复杂度O(n\times M\times M)的暴力DP很好给出,设dp[i][j][k]表示已经放了i个物品,黄色的有j重量,圆粒的有k重量的方案数,每次枚举整个豆荚放入哪个颜色,然后乘上放入的圆皱方案数

首先不考虑有限制的豆子

考虑这个东西可以先把豆荚染色,然后由于第二性征和第一性征没有联系,那么就考虑分开转移,然后方案相乘

复杂度O(n\times m)

发现没办法处理有限制的豆子

那么对于无毒的豆荚,可以继续按上面的转移,豆子也是

对于有毒的豆荚,因为有限制,那么需要暴力转移

dp[i][j][k]表示已经在有毒的选了i个,绿色的有j的重量,圆粒的有k的重量的方案数

大概转移dp[i][j][k]=dp[i-1][j-valj][k-valk]+...

然后考虑把背包合并,大概就是枚举无毒的选绿色有多少重量,选圆粒的有多少重量

然后在重量允许的范围内枚举,有毒的选的重量,然后相乘得到总方案

大概就是几个背包的合并

一些细节问题,就是说这个转移颜色的时候,显然是一个豆荚一个豆荚转移,如果这个豆荚有一个有问题,就得全部摘出来

那么还有就是最后怎么合并,大概就是枚举那些有问题的豆荚是怎么选择的颜色,然后现在颜色已经确定了,然后再枚举有问题的豆子选哪个颜色,就好了

还有就是这个DP,第一维和第二维是毫无关系的,而且你这个第一维相对于豆荚转移,而第二维相对于豆子去转移

也就是最后合并的时候,我们两个维度表示的总数可能没关系,第一维表示总数是所有限制豆荚,第二维表示的总数是所有限制豆子

那么就显然了

被卡了好久,我一直没看明白G表示的是什么

这个东西不就是我写的超长的转移吗qaq,我自己没看出来

#include<bits/stdc++.h>
#define int long long
#define mod 998244353
#define MAXN 2505
using namespace std;
int n,c,b[MAXN],s[MAXN],f[MAXN],g[MAXN],pre_f[MAXN],pre_g[MAXN],ht[MAXN];
int city_ht[MAXN],city_sum[MAXN],F[MAXN][MAXN],G[MAXN][MAXN];
void sol()
{
cin>>n>>c;
int C0,C1,D0,D1,All=0;
for(int i=1;i<=c;i++)
{
city_ht[i]=false;
city_sum[i]=0;
}
cin>>C0>>C1>>D0>>D1;
for(int i=1;i<=n;i++)
{
cin>>b[i]>>s[i];
ht[i]=-1;
city_sum[b[i]]+=s[i];
All+=s[i];
}
int K,x;
cin>>K;
for(int i=1;i<=K;i++)
{
cin>>x;
cin>>ht[x];
city_ht[b[x]]=true;
}
memset(f,0,sizeof(f));
pre_f[0]=f[0]=1;
for(int i=1;i<=c;i++)
{
if(city_ht[i]||(!city_sum[i])) continue;
for(int j=C0;j>=city_sum[i];j--)
{
f[j]=(f[j]+f[j-city_sum[i]])%mod;
}
}
for(int i=1;i<=C0;i++) pre_f[i]=(pre_f[i-1]+f[i])%mod;
memset(g,0,sizeof(g));
pre_g[0]=g[0]=1;
for(int i=1;i<=n;i++)
{
if(ht[i]==-1)
{
for(int j=D0;j>=s[i];j--)
{
g[j]=(g[j]+g[j-s[i]])%mod;
}
}
}
for(int i=1;i<=D0;i++) pre_g[i]=(pre_g[i-1]+g[i])%mod;
int Cs=0,Ss=0;
memset(F,0,sizeof(F));F[0][0]=1;
memset(G,0,sizeof(G));
for(int ct=1;ct<=c;ct++)
{
if(city_ht[ct])
{
Cs+=city_sum[ct];
Cs=min(Cs,C0);
for(int i=0;i<=Cs;i++)
{
for(int j=0;j<=Ss;j++)
{
G[i][j]=F[i][j];
}
}
for(int a=1;a<=n;a++)
{
int t=s[a];
if(b[a]==ct&&ht[a]!=-1)
{
Ss+=s[a],Ss=min(Ss,D0);
if(ht[a]==1)
{
for(int i=0;i<=Cs;i++)
{
for(int j=Ss;j>=t;j--)
{
F[i][j]=F[i][j-t];
}
for(int j=t-1;j>=0;j--) F[i][j]=0;
}
}
if(ht[a]>=2)
{
for(int i=0;i<=Cs;i++)
{
for(int j=Ss;j>=t;j--)
{
F[i][j]=(F[i][j]+mod+F[i][j-t])%mod;
}
}
}
if(ht[a]==3)
{
for(int i=0;i<=Cs;i++)
{
for(int j=Ss;j>=t;j--)
{
G[i][j]=G[i][j-t];
}
for(int j=t-1;j>=0;j--) G[i][j]=0;
}
}
if(ht[a]<=1)
{
for(int i=0;i<=Cs;i++)
{
for(int j=Ss;j>=t;j--)
{
G[i][j]=(G[i][j]+mod+G[i][j-t])%mod;
}
}
}
}
}
for(int j=0,t=city_sum[ct];j<=Ss;j++)
{
for(int i=Cs;i>=t;i--) F[i][j]=F[i-t][j];
for(int i=t-1;i>=0;i--) F[i][j]=0;
}
for(int i=0;i<=Cs;i++)
{
for(int j=0;j<=Ss;j++)
{
F[i][j]=(F[i][j]+mod+G[i][j])%mod;
}
}
}
}
int res=0;
for(int i=0;i<=Cs;i++)
{
for(int j=0;j<=Ss;j++)
{
int l1=max(0ll,All-C1-i),r1=C0-i;if(l1>r1) continue;
int l2=max(0ll,All-D1-j),r2=D0-j;if(l2>r2) continue;
int vf=pre_f[r1];
if(l1) vf=(vf+mod-pre_f[l1-1])%mod;
int vg=pre_g[r2];
if(l2) vg=(vg+mod-pre_g[l2-1])%mod;
res=(res+mod+vf*vg%mod*F[i][j]%mod)%mod;
}
}
cout<<res<<endl;
}
int T;
signed main()
{
cin>>T;
while(T--) sol();
}
/*
1
10 10
100 98 100 93
5 10
4 5
1 10
3 10
7 10
7 10
5 10
3 10
4 10
1 10
5
1 1
3 2
5 1
4 0
2 2 */

省选联考$2021$滚榜

会了费用提前就很简单了

//有个东西叫费用提前
//当你枚举这个选了多少个的时候,为了保证后面的也是
//那么后面的就统一加上,然后那么这个时候差不变
//该加多少还是加多少
#include<bits/stdc++.h>
#define int long long
using namespace std;
int dp[1<<13][15][505],a[15],Ans,n,m;
int lowbit(int x)
{
return x&(-x);
}
int Count(int num)
{
int res=0;
while(num)
{
res++;
num-=lowbit(num);
}
return res;
}
signed main()
{
cin>>n>>m;
int Max=0;
a[0]=-1;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]>a[Max])
{
Max=i;
}
}
for(int i=1;i<=n;i++)
{
int tar=n*(a[Max]-a[i]+(Max<i));
if(tar<=m)
{
dp[1<<(i-1)][i][tar]=1;
}
}
for(int i=1;i<=(1<<n)-1;i++)
{
int Num=Count(i);
for(int j=1;j<=n;j++)
{
if((i>>(j-1))&1)
{
for(int k=0;k<=m;k++)
{
for(int z=1;z<=n;z++)
{
if(!((i>>(z-1))&1))
{
int tar=k+(n-Num)*max(0ll,a[j]-a[z]+(j<z));
if(tar<=m)
dp[i|(1<<(z-1))][z][tar]+=dp[i][j][k];
}
}
}
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
Ans+=dp[(1<<n)-1][i][j];
}
}
cout<<Ans<<endl;
}

DP选讲的更多相关文章

  1. PJ可能会用到的动态规划选讲-学习笔记

    PJ可能会用到的动态规划选讲-学习笔记 by Pleiades_Antares 难度和速度全部都是按照普及组来定的咯 数位状压啥就先不讲了 这里主要提到的都是比较简单的DP 一道思维数学巧题(补昨天) ...

  2. PJ考试可能会用到的数学思维题选讲-自学教程-自学笔记

    PJ考试可能会用到的数学思维题选讲 by Pleiades_Antares 是学弟学妹的讲义--然后一部分题目是我弄的一部分来源于洛谷用户@ 普及组的一些数学思维题,所以可能有点菜咯别怪我 OI中的数 ...

  3. 正睿OI DAY3 杂题选讲

    正睿OI DAY3 杂题选讲 CodeChef MSTONES n个点,可以构造7条直线使得每个点都在直线上,找到一条直线使得上面的点最多 随机化算法,check到答案的概率为\(1/49\) \(n ...

  4. 2019暑期金华集训 Day6 杂题选讲

    自闭集训 Day6 杂题选讲 CF round 469 E 发现一个数不可能取两次,因为1,1不如1,2. 发现不可能选一个数的正负,因为1,-1不如1,-2. hihoCoder挑战赛29 D 设\ ...

  5. [转载]CSP-J/S 第一轮知识点选讲

    CSP-J/S 第一轮知识点选讲 转载自这里 感谢原博主的大力整理! 信息学史及基本知识 一.信息学及计算机史 计算机的顶级奖项:图灵奖.冯·诺依曼奖 图灵奖:由ACM(美国计算机协会)设立于1966 ...

  6. [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)

    转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识……这真的是一种很锻炼人的题型…… 每一道题的状态都不一样 ...

  7. [胡泽聪 趣题选讲]大包子环绕宝藏-[状压dp]

    Description 你有一个长方形的地图,每一个格子要么是一个障碍物,要么是一个有一定价值的宝藏,要么是一个炸弹,或者是一块空地.你的初始位置已经给出.你每次可以走到上.下.左.右这四个相邻的格子 ...

  8. [提升性选讲] 树形DP进阶:一类非线性的树形DP问题(例题 BZOJ4403 BZOJ3167)

    转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7337179.html 树形DP是一种在树上进行的DP相对比较难的DP题型.由于状态的定义多种多样,因此解法也五 ...

  9. ZROI 暑期高端峰会 A班 Day5 杂题选讲

    CF469E \(n\) 个需要表示的数,请使用最少的 \(2^k\) 或 \(-2^k\) 表示出所有需要表示的数.输出方案. \(n\le 10^5,|a_i|\le 10^5\). 首先每个数肯 ...

随机推荐

  1. There appears to be trouble with your network connection. Retrying…

    yarn 错误There appears to be trouble with your network connection. Retrying- 原因:yarn超时 解决途径: #查看代理 yar ...

  2. js算法-埃筛法

  3. 通过一次生产case深入理解tomcat线程池

    最近生产上遇到一个case,终于想明白了原因,今天周末来整理一下 生产case 最近测试istio mesh的预热功能(调用端最小连接数原则) 来控制调用端进入k8s刚扩出来的容器的流量 因为刚启动的 ...

  4. Java泛型知识总结

    泛型 前言 在没有泛型之前,程序员必须使用Object编写适用于多种类型的代码.很繁琐,也不安全. 泛型的引入使Java有了一个很强的类型系统,允许设计者详细地描述变量和方法的类型要如何变化. 在普通 ...

  5. Bean Validator

    Bean Validator 关于Jakarta EE 2018年03月, Oracle 决定把 JavaEE 移交给开源组织 Eclipse 基金会,并且不再使用Java EE这个名称. 因此jav ...

  6. 轻松上手Fluentd,结合 Rainbond 插件市场,日志收集更快捷

    以往有篇文章介绍 EFK(Kibana + ElasticSearch + Filebeat)的插件日志收集.Filebeat 插件用于转发和集中日志数据,并将它们转发到 Elasticsearch ...

  7. 《ECMAScript 6 入门》【三、字符串的扩展】(持续更新中……)

    前言: 本篇介绍 ES6 对字符串的改造和增强.一.字符的 Unicode 表示法 字符的 Unicode 码点必须在\u0000~\uFFFF之间,\uxxxx形式表示一个字符,其中xxxx表示字符 ...

  8. node图片压缩的两员大将

    一.ishrink 全局安装 npm i ishrink -g 1.按url方式压缩 本地图片地址 sk -u C:\Users\admin\Desktop\images\img 网络图片地址 sk ...

  9. 方法重载、方法重写、四种权限修饰、JavaBean、代码块

    方法重载(overload) 一个类中可以含有多个重名的方法. 两同一不同 ①同一个类 ②同一个方法名 ③不同参数列表:参数个数不同,参数类型不同 方法重写(override) ①子类重写的方法的修饰 ...

  10. Java 向数组中添加元素

    一般数组是不能添加元素的,因为他们在初始化时就已定好长度了,不能改变长度. 向数组中添加元素思路 第一步:把数组转化为集合 list = Arrays.asList(array); 第二步:向集合中添 ...