动态规划总结(持续更新中……)

news2024/10/5 14:14:47

注意:我这里定义的所有dp的索引相对于实际问题都是从1开始的,也就是空间长度会比实际大1,这样的好处是在部分题目场景下不需要条件判断也不会越界。

字符串/数组类

区间

1.最长回文子串

dp定义

dp[i][j]表示第i个字符到第j个字符组成的子字符串是否是回文串(这里i,j都是从1开始的)

boolean[][] dp = new boolean[n + 1][n + 1];(n是字符串长度)

转移方程

如果从第i+1个字符到第j-1个字符组成的子字符串是回文字符串,那么如果第i个字符和第j个字符相等,那么从第i个字符到第j个字符组成的子字符串是回文字符串,表示如下:

dp[i][j] = dp[i + 1][j - 1] if s.charAt(i - 1) == s.charAt(j - 1) 
(ps:s表示字符串,因为索引从0开始所以用i-1和j-1)

2.猜数字大小II

dp定义

通常我们定义都是n+1空间,这里定义n+2,是因为后面区间内dp文件中,右区间刚好为n了,但是需要划分n-1和n+1两部分,如果不定义为n+2,那么n+1这部分作为索引就会越界。

dp[i][j]表示从第i到第j区间的数确保能获胜的最小金额(不管选哪个数字),自然最后结果是返回dp[1][n]了

int[][] dp = new int[n + 2][n + 2];

转移方程

对于区间[i,j]存在选择choice∈[i,j],由于要保证稳赢,那么肯定不能直接choice就选中,没选中的话,就需要花费choice,然后从区间[i,choice-1]和[choice+1,j]中去求解子问题,因为要稳赢所以取左右两个区间中的最大成本花费,由于最后要选择最小成本,所以从所有choice中选择稳赢的且花费最少的,具体表示如下:

//max确保稳赢,min在稳赢的基础上选择最小的成本
dp[i][j] = Math.min(dp[i][j], Math.max(dp[i][choice - 1], dp[choice + 1][j]) + choice]);

前缀

1.解码方法

dp定义

dp[i]表示前i个字符组成的字符串的解码方式数

int[][] dp = new int[n + 1];(n是字符串长度)

转移方程

已知前i-2个字符组成的字符串和前i-1个字符组成的字符串的解码方式数,如果第i个字符不等于0,同时第i-1个字符满足不等于0且和第i位组成的两位数字符不大于26,那么第i个字符和第i-1个字符可以合并解码也可以单独解码,同理其他情况,只能第i位单独解码或者只能第i位和第i-1位字符一起解码,表示如下:

//最后一个字符单独解码码
if(s[i-1]!='0'){
    dp[i]+=dp[i-1];
}
//倒数第二位不是0,且倒数两位不大于26,即1~26
if(i>1 && (s[i-2]=='1' || (s[i-2]=='2' && s[i-1]>='0' && s[i-1]<='6'))){
    dp[i]+=dp[i-2];
}
总的来说
dp[i]=dp[i-1] 最后一位单独编码
dp[i]=dp[i-2]    最后两位一起编码
dp[i]=dp[i-1]+dp[i-2] 单独一起均可

2.交错字符串

dp定义

dp[i][j]表示s1的前i个元素和s2的前j个元素是否能交错构成s3的前i+j个元素。

boolean[][] dp = new boolean[m + 1][n + 1];
(m表示s1的长度,n表示s2的长度)

转移方程

如果s1的前i-1个元素和s2的前j个元素能交错构成s3的前i+j-1个元素,那么如果s1的第i个元素等于s3的第i+j个元素,那么s1的前i个元素和s2的前j个元素也能交错构成s3的前i+j个元素;对于s2的前j-1个元素的情况也同理,表示如下:

dp[i][j] =  dp[i][j] || 
(s1.charAt(i - 1) == s3.charAt(i + j - 1) && dp[i - 1][j]);
dp[i][j] =  dp[i][j] || 
(s2.charAt(j - 1) == s3.charAt(i + j - 1) && dp[i][j - 1]);
(ps:在索引s1/s2/s3时候由于其索引从0开始,所以第i个元素索引是i-1
,第i+j个元素索引是i+j-1)

3.单词拆分

dp定义

dp[i]表示前i个字符组成的子串能否被单词拆分

boolean[] dp = new boolean[n + 1];

转移方程

如果长度为len的部分等于单词表中的某个单词,那么dp[i]可以由dp[i - len]转移过来,具体表示如下:

if(i>=len&&s.substr(i-len,len)==wordDict[j]) {
    dp[i]=dp[i-len] ||dp[i];
}

4.乘积最大子数组

dp定义

由于这题存在负数,由于负负得正的情况,也需要同时记录连续子数组的最小乘积。其中maxDp[i]表示以i结尾的连续子数组中的最大连续子数组的乘积,minDp[i]表示以i结尾的连续子数组中的最小连续子数组的乘积。

int[] maxDp = new int[n + 1];
int[] minDp = new int[n + 1];

转移方程

由于可能存在一个极小的负数乘上负数为最大值,所以在maxDp转移的时候应该要考虑minDp,同理可能存在一个极大的整数乘上负数为最小值,所以在minDp转移的时候应该要考虑maxDp,当然也有可能nums[i - 1]最大/小,最新的从第i个数开始重新算连续子数组最大/小值。表示如下

 maxDp[i] = max(maxDp[i - 1] * nums[i - 1], max(nums[i - 1], minDp[i - 1] * nums[i - 1]));
 minDp[i] = min(minDp[i - 1] * nums[i - 1], min(nums[i - 1], maxDp[i - 1] * nums[i - 1]));

5.最长递增子序列

dp定义

dp[i]表示以i结尾的最长子递增子序列长度

int[] dp = new int[n + 1];

转移方程

对于j<i,dp[i]如何由dp[j]转移过来呢?很显然,只要nums[i -1]>nums[j -1]满足严格递增,那么dp[j]+1就可以作为dp[i]的一个备选方案,由于j∈[1,i),所以需要在所有方案中取最大值。具体表示如下:

if(nums[j-1]<nums[i-1]){
    dp[i]=max(dp[j]+1,dp[i]);
}

6.买卖股票的最佳时机含冷冻期

dp定义

dp[i][j]表示到第i天后的最大利润,j为0,1,2,3分别表示不同状态,为0时表示此时不持股且非卖出(进一步表示明天不在冷冻期可以直接买),为1表示为卖出状态,为2表示处于冷冻期,为3表示持股状态(即买入)。最后的结果就是从0~2三种状态中取最大值。

int[][] dp = new int[n + 1][4];

转移方程

1.对于为0时,表示此时不持股且非卖出,那么其前一天的状态可能:①冷冻期(即为2时),②此时不持股且非卖出(即为0时)。所以其状态转移方程如下:

dp[i][0]=max(dp[i-1][0],dp[i-1][2]);

2.对于为1的时候,表示卖出状态,那么其前一天的状态可能:①持股状态(即为3)。所以其状态转移方程如下。卖出利润自然需要加上prices[i - 1]:

dp[i][1]=dp[i-1][3]+prices[i-1];

3.对于为2时,表示冷冻期,那么其前一天的状态可能为:①卖出状态(即为1)。所以其状态转移方程如下:

 dp[i][2]=dp[i-1][1];

4.对于为3时,表示持股状态,其前一天的状态可能为:①此时不持股且非卖出(即为0),②冷冻期(即为2时),③持股状态(即为3),那么状态转移方程如下,三中情况取最大值:

dp[i][3]=max(dp[i-1][0]-prices[i-1],dp[i-1][2]-prices[i-1]);
dp[i][3]=max(dp[i][3],dp[i-1][3]);(ps:由于不能同时参与多笔交易,必须在再次购买前出售掉之前的股票,所以这里对于3的转移不能继续买入)

7.最大整除子集

dp定义

dp[i]表示前i个数字且以i为结尾的最长整数子集的长度

 int[] dp = new int[n + 1];

转移方程

对于j∈[1,i),如果满足nums[i-1]%nums[j-1]==0,那么dp[j]+1和dp[i]中去最大值就可以转移到dp[i]。表示如下:

dp[i] = Math.max(dp[i],d[j]+1);

8.摆动序列

dp定义

其中upDp[i]表示以第i个数为结尾的最长摆动子序列长度,且该子序列最后一位大于倒数第二位;downDp[i]表示第i个数为结尾的最长摆动子序列长度,且该子序列最后一位小于倒数第二位。最后结果就是返回upDp[n]和downDP[n]的最大值。

 int[] upDp = new int[n + 1];
 int[] downDp = new int[n + 1];
// 可以都初始化为1
 Arrays.fill(upDp, 1);
 Arrays.fill(downDp, 1);

转移方程

对于第i个数nums[i-1]如果大于第i-1个数nums[i-2],那么upDp[i]就可以由downDp[]i-1]转移过来,长度+1,对于upDp[i]其由upDp[i-1]直接转移得到,长度不变,只是子序列最后一位由nums[i-2]替换为了nums[i-1];同理第i个数nums[i-1]如果小于第i-1个数nums[i-2],那么downDP[i]就可以由upDp[i-1]转移过来,长度+1,对于downDp[i]其由downDp[i-1]直接转移得到,长度不变,只是子序列最后一位由nums[i-2]替换为了nums[i-1];如果相等,那么upDp[i]和downDp[i]分别相对于upDp[i-1]和downDp[i-1]长度没有变,只是子序列最后一位由nums[i-2]替换为了nums[i-1]。具体表示如下:

if(nums[i-2]>nums[i-1]){
   downDp[i]=max(downDp[i-1],upDp[i-1]+1);
   upDp[i]=upDp[i-1];
}else if(nums[i-2]<nums[i-1]){
   upDp[i]=max(upDp[i-1],downDp[i-1]+1);
   downDp[i]=downDp[i-1];
}else{
   upDp[i]=upDp[i-1];
   downDp[i]=downDp[i-1];
}

网格类

1.不同路径

dp定义

dp[i][j]表示走到第i行,第j列(从1开始)的路径条数

int[][]dp = new int[m + 1][n + 1];(m、n表示网格有几行几列)

转移方程

已知走到第i-1行、第j列的路径条数和走到第i行、第j-1行的路径条数,由于只能向下或者向右走,所以两者相加即可得到走到第i行、第j列的路径条数,表示如下:

dp[i][j] = dp[i - 1][j] + dp[i][j - 1];

2.不同路径 II

和1.不同路径的dp和转移方程一样,不过由于多了障碍物,在初始化和转移的时候需要考虑障碍物的不可达。即加相应条件判断即可。

3.最小路径和

dp定义

dp[i][j]表示走到第i行,第j列(从1开始)的最小路径和

int[][]dp = new int[m + 1][n + 1];(m、n表示网格有几行几列)

转移方程

已知走到第i-1行、第j列的最小路径和和走到第i行、第j-1行的最小路径和,由于只能向下或者向右走一步,所以两者分别加上第i行第j列的网格数取最小值即为走到第i行第j列的最小路径和,表示如下:

dp[i][j]=min(dp[i][j-1],dp[i-1][j])+grid[i-1][j-1]
(ps:grid[i-1][j-1]表示网格第i行第j列的数字)

4.最大正方形

dp定义

dp[i][j]表示以第i行第j列位置为右下角的最大只包含1的正方形的边长,由于题目最后结果是求面积,正方形边长的平方就是面积。

int[][]dp = new int[m + 1][n + 1];(m、n表示网格有几行几列)

转移方程

当第i行第j列位置为1的时候,那么dp[i][j]的值不仅依赖于dp[i-1][j-1]还依赖于dp[i-1][j]和dp[i][j-1],因为即使dp[i-1][j-1]非常大,但如果dp[i-1][j]或dp[i][j-1]较小会使得dp[i][j]如果按照dp[i-1][j-1]+1直接转移过来的话得到的正方形就不是全为1了,所以需要这三者取最小值保证+1后得到的正方形满足全为1。

if(matrix[i-1][j-1]=='1'){
    dp[i][j]=min(dp[i-1][j-1],min(dp[i][j-1],dp[i-1][j]))+1;
}

类别待定

1.爬楼梯

dp定义

dp[i]表示爬到第i阶楼梯有多少中爬法

int[] dp = new int[n + 1];

转移方程

已知爬到第i-1阶楼梯和爬到i-2阶楼梯的爬法,由于一次只能爬1或2阶,所以两者爬法相加即为爬到第i阶楼梯的爬法,表示如下:

 dp[i] = dp[i - 1] + dp[i - 2];

2.不同的二叉搜索树

dp定义

dp[i]表示i个节点能组成的二叉树个数

int[] dp = new int[n + 1];

转移方程

取j∈[1,i],以j为根节点,第j个数左边部分为左子树,左子树有dp[j - 1]个,右边部分为右子树,右子数有dp[i-j]个,所以以j为根节点的二叉树有dp[j - 1]*dp[i-j],由于j∈[1,i],有多个取值,最终得到 dp[i]=\sum_{j}^{}dp[j - 1]*dp[i - j]

3.三角形最小路径和

dp定义

dp[i][j]表示到达i层第j个位置的最小路径和

int[][] dp = new int[n + 1][n + 1];

转移方程

由于每一步只能移动到下一行中相邻的结点上,所以dp[i][j]可以由dp[i-1][j-1]或dp[i-1][j]移动得到。表示如下:

dp[i][j] = Math.min(dp[i-1][j-1],dp[i-1][j]) + triangle[i - 1][j - 1];
(triangle中索引从0开始,所以第i层,第j个数,索引为i-1和j-1)

4.打家劫舍

dp定义

dp[i]表示抢劫到第i个房子时的最大现金。

int[] dp = new int[n + 1];

转移方程

由于不能连续抢劫两间相邻的,所以要准备抢劫第i间时,只能从dp[i-2]转移,也可以选择不抢劫第i间时,从dp[i - 1]转移,表示如下:

dp[i]=max(dp[i-1],dp[i-2]+nums[i-1]);

5.打家劫舍 II

同4.打家劫舍一样,不过由于第一家和最后一家不能共存,在做的时候需要分别考虑两种,即1~n-1和2~n。

6.丑数 II

dp定义

dp[i]表示第i个丑数

int[] dp = new int[n + 1];

转移方程

由于丑数只包含质因数2、3或5的正整数(ps:1也算,是个例外),所以说对于dp[i]的转移一定是从前面的丑数乘上2或者3或者5得到的,也就是说存在j<i,使得dp[i] = dp[j] *(2或3或5)。由于丑数顺序是从小到大,所以需要每次取乘2或3或5的结果的最小值,同时对于乘的不同情况,j的值也会不同,具体表示如下:

dp[i]=min(dp[p2]*2,min(dp[p3]*3,dp[p5]*5));
if(dp[i]==dp[p2]*2) ++p2;
if(dp[i]==dp[p3]*3) ++p3;
if(dp[i]==dp[p5]*5) ++p5;

7.完全平方数

dp定义

dp[i]表示和为i的完全平方数的最小数量

int[] dp = new int[n + 1];

转移方程

由于转移的过程实际上是完全平方数的增加的过程,例如dp[i]就是从dp[i-1],dp[i-4],dp[i-9]……中找出最小的然后+1转移过来的,也就是说dp[i]=dp[i-完全平方数]+1,具体表示如下:

for(int i=1;i*i<=n;i++){
    for(int j=i*i;j<=n;j++){
       dp[j]=min(dp[j],dp[j-i*i]+1);
    }
}

8.超级丑数

dp定义

dp[i]表示第i个丑数

int[] dp = new int[n + 1];

转移方程

这题本质上和6.丑数II一样,不过是primes数组从2、3、5变成了还有其他可能罢了,具体表示如下:

for(int i=0;i<m;i++){
    min_res=min(min_res,dp[p[i]]*primes[i]);
}
dp[i]=min_res;
for(int i=0;i<m;i++){
    if(min_res==dp[p[i]]*primes[i]){
        ++p[i];
    }
}

9.零钱兑换

dp定义

dp[i]表示筹齐总金额i需要的最少硬币个数

int[] dp = new int[n + 1];

转移方程

这题就是1.爬楼梯的一个升级版,爬楼梯相当于只有面值1和2的硬币可选,类比于一次可以爬1阶或者2阶。这题的硬币组合由题目给出,所以每次可以选择一个硬币进行状态转移。具体表现如下,coin是各种可供选择的硬币,最后从各种选择选择最小的:

dp[j]=min(dp[j-coin]+1,dp[j]);

10.打家劫舍III

dp定义

dp(n)表示选择节点n后以n为根节点的子树能盗取的最大金额,由于n是节点,不是数字,不能作为索引,所以这题dp不用数组,用map。同理np(n)表示不选择节点n后以n为根节点的子树能盗取的最大金额。

表示不选择节点n后以n为根节点的子树能盗取的最大金额
Map<TreeNode, Integer> dp = new HashMap<>();
Map<TreeNode, Integer> np = new HashMap<>();

转移方程

假如存在一个根节点,如果选择了该根节点,那么其左右孩子就不能被选,那么以该根节点为根的子树能盗取的最大金额转移表示如下:

dp.put(root, np.getOrDefault(root.left, 0) + np.getOrDefault(root.right, 0) + root.val);

如果没有选择该根节点,那么其左右孩子就可选可不选,那么以该根节点为根的子树能盗取的最大金额转移表示如下:

np.put(root, Math.max(dp.getOrDefault(root.left, 0), np.getOrDefault(root.left, 0)) 
        + Math.max(dp.getOrDefault(root.right, 0), np.getOrDefault(root.right, 0)));

11.比特位计数

dp定义

dp[i]表示数i的二进制表示中1的个数

int[] dp = new int[n + 1];

转移方程

当一个数与该数-1的按位与为0时,表示这个数是2的次幂,因为2的次幂的二进制表示只有一个1且该1是最高位,减1之后那么自然得到就是最高位为0以及后面位全是1的结果了。应该我们可以用highestBit记录当前的最高位,表示如下:

if ((i & (i - 1)) == 0) {
    //说明是2的次幂
    highestBit = i;
}

那么我比你多一个最高位,显然就比你多了一个1,转移方程表示如下:

dp[i] = dp[i - highestBit] + 1;

12.整数拆分

dp定义

dp[i]表示数i能拆分成的整数的最大乘积

int[] dp = new int[n + 1];

转移方程

转移的情况明显就是拆或者不拆,设j∈[1,i),那么如果i-j拆分,那么dp[i-j]*j即可转移到dp[i],如果i-j不拆分,那么(i-j)*j可以转移到dp[i],具体表示如下:

dp[i]=max(dp[i],max(dp[i-j]*j,(i-j)*j));

13.统计各位数字都不同的数字个数

dp定义

dp[i]表示给定整数i,满足条件的数的个数。

int[] dp = new int[n + 1];

转移方程

首先对于dp[i]在dp[i-1]的基础上多出来了位数为i的满足各个位上数字都不同的数字,所以对于dp[i-1]到dp[i]的转移可以从这部分多出来了位数为i的满足各个位上数字都不同的数字入手。其次我们要知道dp[i-1]-dp[i-2]就是多出来的位数为i-1的满足各个位上数字都不同的数字,显然由于dp[i-1]-dp[i-2]就是多出来的位数为i-1的满足各个位上数字都不同的数字,那么在确定了前i-1位后,最后一位不能和前面的重复,其选择为10-(i-1),因此满足要求的位数为i的数共有(dp[i-1]-dp[i-2])*(10-(i-1))个。因此转移方程表示如下:

 dp[i] = dp[i - 1] + (dp[i - 1]- dp[i -2]) * (10 - (i - 1));

14.组合总数IV

dp定义

dp[i]表示值为i的元素组合数。

int[] dp = new int[n + 1];

转移方程

对于nums数组,存在数组中的数num,dp[i]为所有的dp[i-num]的和。表示如下:

for(auto& num:nums){
    if(i>=num && dp[i-num]<INT_MAX-dp[i]){
        dp[i]+=dp[i-num];
    }
}

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

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

相关文章

一文了解VR全景,VR全景有哪些优势?

引言&#xff1a; VR全景技术近年来崭露头角&#xff0c;已经成为宣传领域的一大亮点。不仅在娱乐&#xff0c;旅游行业广泛应用&#xff0c;还在商业和教育等领域崭露头角。 一&#xff0e;什么是VR全景&#xff1f; VR全景&#xff0c;全名Virtual Reality Panorama&#x…

Python代码扫描:新一代 Python Linter工具Ruff -极力推荐-快的原因是Rust写的?

目录 RUFF概述 特点 安装和使用 应用场景 配置 编辑器集成 PyCharm(外部工具) Ruff的规则 Ruff速度快的几个原因 最后 注意&#xff1a;后续技术分享&#xff0c;第一时间更新&#xff0c;以及更多更及时的技术资讯和学习技术资料&#xff0c;将在公众号CTO Plus发布…

多线程和并发编程(2)—CAS和Atomic实现的非阻塞同步

在并发编程中实现原子操作可以使用锁&#xff0c;锁机制满足基本的需求是没有问题的了&#xff0c;但是有的时候我们的需求并非这么简单&#xff0c;我们需要更有效&#xff0c;更加灵活的机制&#xff0c;synchronized关键字是基于阻塞的锁机制&#xff0c;也就是说当一个线程…

零代码编程:用ChatGPT来批量删除特定文件

一个文件夹中有很多个文件重复了&#xff0c;重复的文件中都含有“&#xff08;1&#xff09;”这样的字符&#xff0c;需要把所有这些文件批量删除掉。 在ChatGPT中输入如下提示词&#xff1a; 你是一个Python编程专家&#xff0c;写一段代码完成批量删除文件的任务&#xff…

【java】【SSM框架系列】【四】SpringBoot

目录 一、SpringBoot简介 1.1 入门案例 1.1.1 案例 1.1.2 Spring程序与SpringBoot区别 1.1.3 SpringBoot项目快速启动 1.2 SpringBoot概述 二、基础配置 2.1 配置文件格式 2.1.1 配置文件格式&#xff08;3种&#xff09; 2.1.2 配置文件间的加载优先级&#xff08;了解…

电视机顶盒哪个牌子好?拆机达人盘点网络电视机顶盒排名

电视机顶盒哪个牌子好&#xff1f;在挑选电视机顶盒的时候&#xff0c;我们要注意的是盒子的芯片、内存以及系统和操作等等方面全都要衡量&#xff0c;根据我多年拆机经验来说&#xff0c;有些产品存在虚标配置、偷工减料等情况&#xff0c;在选购时不懂行可以参考以下网络电视…

【mysql】—— 函数的基本介绍

前言&#xff1a; MySQL是一种常用的关系型数据库管理系统&#xff0c;它提供了许多内置的函数来进行数据操作和处理。本期&#xff0c;我将给大家介绍的就是关于 “函数” 的相关知识&#xff01;&#xff01;&#xff01; 目录 &#xff08;一&#xff09;日期函数 &#…

调整Pycharm中代码的字体的大小

注意&#xff1a;是代码的字体大小&#xff0c;不是Pycharm标题栏、状态栏啥的字体的大小。 1、第一步 2、第二步&#xff0c;勾选“用ctrl滚轮”调整字体大小 3、在代码框中&#xff0c;ctrl鼠标滚轮就能调节代码字体大小了。

《程序员职场工具库》认识 OGSM 模型

最近简单学习了一下 OGSM 模型&#xff0c;把一些学习感想给大家分享一下。可能我们用不到这个模型&#xff0c;但是也算是一个小知识点&#xff0c;留个印象也不错。 OGSM 模型是企业战略管理的理论工具。它主要是以下 4 个部分&#xff1a; O&#xff08;Objective&#xf…

ChromeDriver最新版(116.x及最新)下载途径分享

首先查看version&#xff1a;在地址栏输入chrome://version/ 最新版 官方地址&#xff1a;https://googlechromelabs.github.io/chrome-for-testing/ 选择合适的下载即可 Old 官网&#xff1a;https://chromedriver.chromium.org/downloads 国内镜像 ps:国内镜像没有…

基于C#的图书管理系统数据库设计报告

第一章 问题描述 1.1 图书管理系统简介 本系统利用.NET处理数据库的功能&#xff0c;实现对图书馆信息的管理。主要功能为管理有关读者、出版社、书籍、借阅和管理者的信息等。 本系统的结构分为读者信息管理模块、出版社信息管理模块、书籍信息管理模块、借阅信息管理模块、…

腾讯云轻量应用服务器详细介绍_轻量值得买吗?

腾讯云轻量应用服务器开箱即用、运维简单的轻量级云服务器&#xff0c;CPU内存带宽配置高并且价格特别优惠&#xff0c;轻量2核2G3M带宽95元一年、2核2G4M优惠价112元一年&#xff0c;396元三年、2核4G5M带宽168元一年&#xff0c;628元3年、4核8G12M带宽446元一年&#xff0c;…

面经pc端项目

创建项目 安装脚手架-----创建项目------选择自定义 sass基础语法 https://www.sass.hk/ sass语法有两个:sass(旧) scss(新) 1.scss语法 和less语法类似,支持嵌套,支持变量… scss: $变量名 less: @变量名 $color:orange; .box{width: 400px;height: 400px;borde…

Linux 修改SSH的显示样式,修改终端shell显示的样式,美观更改

要修改SSH的显示样式&#xff0c;您可以使用自定义的PS1&#xff08;提示字符串1&#xff09;变量来更改命令行提示符的外观。在您的情况下&#xff0c;您想要的格式似乎包括日期和时间&#xff0c;以及当前目录。以下是一个示例PS1设置&#xff0c;可以实现您所描述的样式&…

LVS -DR

一、DR模式数据包流向分析 1.Client 客户端发送请求到 Director Server&#xff08;负载均衡器&#xff09;&#xff0c;请求的数据报文&#xff08;源IP是 CIP&#xff0c;目的IP 是VIP&#xff09;到达内核空间。 2.Director Server&#xff08;负载均衡器&#xff09;和 R…

【猿灰灰赠书活动 - 06期】- 【计算机考研书单——408专属】

&#x1f468;‍&#x1f4bb;本文专栏&#xff1a;赠书活动专栏&#xff08;为大家争取的福利&#xff0c;免费送书&#xff09; &#x1f468;‍&#x1f4bb;本文简述&#xff1a;博文为大家争取福利&#xff0c;与机械工业出版社合作进行送书活动 &#x1f468;‍&#x1f…

【软件测试】设计优秀的测试用例

前言 我从来没有好好的写过一个测试用例&#xff0c;之前做开发虽然写单元测试和流程测试&#xff0c;基本上都是基于自己的代码&#xff0c;而且单元测试和流程测试的框和规范已经非常完善&#xff0c;你只需要填空就行&#xff0c;后来转做自动化测试&#xff0c;但我的做事…

Python入门教程 | Python 函数与参数

函数简介 函数是组织好的&#xff0c;可重复使用的&#xff0c;用来实现单一&#xff0c;或相关联功能的代码段。 函数能提高应用的模块性&#xff0c;和代码的重复利用率。你已经知道Python提供了许多内建函数&#xff0c;比如print()。但你也可以自己创建函数&#xff0c;这…

【数据结构】 Map和Set详解

文章目录 &#x1f340;Map与Set的概念及场景&#x1f333;Map与Set模型介绍&#x1f3a8;Map 的使用&#x1f4cc;Map说明&#x1f4cc;Map.Entry<K, V>的说明&#x1f4cc;Map 的常用方法说明&#x1f6a8;注意事项&#x1f6a9;TreeSet的使用 &#x1f38b;Set 的说明…

无涯教程-JavaScript - IPMT函数

描述 IPMT函数根据定期,固定的还款额和固定的利率返回给定投资期限内的利息支付。 语法 IPMT (rate, per, nper, pv, [fv], [type])争论 Argument描述Required/OptionalRateThe interest rate per period.RequiredPerThe period for which you want to find the interest a…