专题十八_动态规划_斐波那契数列模型_路径问题_算法专题详细总结

目录

动态规划

动态规范五步走:

1. 第 N 个泰波那契数(easy)

解析:

1.状态表达式:

2.状态转移方程:

3.初始化:

4.填表顺序:

5.返回值

编写代码:

总结:

2. 三步问题(easy)

解析:

总结:

3. 使⽤最⼩花费爬楼梯(easy)

解析:

总结:

4. 解码⽅法(medium)

解析:

方法一:

优化:

总结:

路径问题

5. 不同路径(medium)

解析:

1.状态表达式:

2.状态转移方程:

3.初始化:

4.填表方向:

5.返回值:

编写代码:

总结:

6. 不同路径II(medium)

解析:

总结:

7. 礼物的最⼤价值(medium)

解析:

总结:

8. 下降路径最⼩和(medium)

解析:

总结:

9. 最⼩路径和(medium)

解析:

总结:

10. 地下城游戏(hard)

解析:

1.状态表达式:

2.状态转移方程:

这里考虑两种情况:

3.初始化:

4.填表顺序:

5.返回值:

代码编写:

总结:

独立解决一道困难题真的很帅好吧,xdm 给点鼓励~!!!

总结一下吧~总结不易,本章节对我的收获巨大,希望对你也是~!!!


动态规划

经过前面的优选算法,也算是一步步走到现在,前面学过了双指针、滑动窗口、二分、模拟、dfs、bfs等等一些列小的算法专题,有了很多不一样的收获和感悟。学到现在,有了一个新的总结体会:学完不总结,等于白学。所以要经常回顾和总结,时不时回头看看来时的路,学的越多忘的越多,一定要时刻回顾、回顾、再回顾!!!

接下来,我们就要进入动态规划专题,开启一篇更难更需要勇气来翻越的一座大山,但我们不能畏惧,而要鼓起勇气,向着这座高峰进发,去征服它,去领略那山顶上更为壮丽的风景。

最后:

所有计算机里的东西只不过都是人想出来的罢了,我们现在不知道,不代表我们未来不明白,我们只是还没学到,总有一天我会学到计算机里面的所有知识,scanf()不过也只是一个函数而已,只是我们还没有来得及去看它的源码,总有一天,我们会明白scanf()里面的一切;

动态规范五步走:

1.状态表达

2.状态转移方程

3.初始化

4.填表顺序

5.返回值

后面的一切动态规划的题目,全部都是由这五步得来,里面最重要的就是:
状态表达式状态转移方程

1. 第 N 个泰波那契数(easy)

题目意思很简单,就是通过题目给定递推公式求出T(n)的结果

解析:

这题很温柔,上来就直接把状态转移方程给我们了,但是我们还是要从0开始,来一步步推出状态表达式和状态转移方程:

1.状态表达式:

1)所谓动态规划就是要先构建一个dp表,然后根据经验+题目要求来总结出dp表内的每一个小格子代表的是什么含义;

2)分析问题的过程中,来发现重复的子问题

就如这道题,首先我们就设置一个线性dp表,来表示每个dp[i]->表示的是第N个泰波那锲数;

2.状态转移方程:

上面分析出了状态表达式,就是每个dp[i]->表示的是第N个泰波那锲数;

那么再有题目给出的T(n+3)=T(n)+T(n+1)+T(n+2)

那么在dp表中就可以推出:

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

3.初始化:

通过上面的状态转移方程可以看到,在一个for()内要是从0开始填表,那么就会有dp[i-3]这种越界的情况,所以,为了保证不会出现越界的情况我们就要从i==3开始填表,这样最小的数也都是dp[0],那么我们就要在一开始就将dp[0]、dp[1]、dp[2]完成初始化;

根据题目要求:dp[0]=0,dp[1]=dp[2]=1;

4.填表顺序:

为了填当前位置的值:

那么我们就需要知道dp[i-3]这些值,就是在dp[i]的前面,所以我们只能先求出前面的值,才能再往后进行递归求解;

所以,填表顺序:从左往右;

5.返回值

题目要求+状态表示,因为每题题目不同,状态表达也不同,所以最后的返回值肯定也不同;

这一题要返回第N个泰波那契数,dp表又表示的是第i个泰波那契数,所以最后返回dp[n]即可;

编写代码:

class Solution {
public:int tribonacci(int n) {if(n==0||n==1) return n;if(n==2) return 1;//因为要返回dp[n] 就只能多开一个空间的大小,能够遍历到dp[n]vector<int> dp(n+1);dp[0]=0,dp[1]=dp[2]=1;for(int i=3;i<=n;i++)dp[i]=dp[i-3]+dp[i-2]+dp[i-1];return dp[n];}
};

总结:

动态规划的题目大体就是这么个流程,可能这题很简单,不能体现出它的强大,但是难的题目也是真的难;好好利用动态规划五步走,相信能够总结出自己的解题方法;

2. 三步问题(easy)

题目意思很简单,就是跟上一题简直一模一样,就是换了一个表达方式,上楼梯的方式有三种,一次可以上1阶或者2阶或者3阶,求上n阶一共有多少种办法。

解析:

1.状态表达式:

2.状态转移方程:

由题目意思可以知道,dp[i]的值是i-1、i-2、i-3这三个位置都可以进行改变的,所以跟他们都有关系那么:

dp[i-1]就表示:到达i-1位置的上楼梯的总次数

dp[i-2]就表示:到达i-2位置的上楼梯的总次数

dp[i-3]就表示:到达i-3位置的上楼梯的总次数

所以dp[i]表示:到达i位置的上楼梯的总次数 = dp[i-1] + dp[i-2] + dp[i-3];

因为前三个位置都可以到达i位置,所以只要知道了前三个位置的次数,就可以得到i位置的总次数

3.初始化:

跟上题一样,这题为了防止越界访问数组,初始化任然是dp[i-3]、dp[i-2]、dp[i-1]三个位置的值;

        vector<int> dp(n+1);//初始化dp[0]=1,dp[1]=1,dp[2]=2;

4.填表顺序:

只有知道前面的值的结果,才能知道当前i位置的值,所以是从左往右进行填表;

5.返回值:

根据题目意思,返回dp[n] ,n位置的总次数,那么就要多开一个空间,防止遍历不到n位置

编写代码:

class Solution {
public:int waysToStep(int n) {if(n==0||n==1) return 1;if(n==2) return 2;vector<int> dp(n+1);//初始化dp[0]=1,dp[1]=1,dp[2]=2;for(int i=3;i<=n;i++){dp[i]=((dp[i-1]+dp[i-2])%1000000007+dp[i-3])%1000000007;}return dp[n];}
};

总结:

看到现在,这类动态规划其实也没有特别难,只要自己能够耐下心来一步步分析,真的就能够很容易的轻松解决掉这类问题;

3. 使⽤最⼩花费爬楼梯(easy)

题目意思是每次爬楼梯前都要先支付当前楼梯的费用,然后可以选择爬1阶或者2阶

解析:

1.状态表达式:

dp[i]表示:达到i位置所需要的最小费用

2.状态转移方程:

题目意思就是每次都可以从前一个阶梯或者前两个阶梯上来到达i位置:

那么每次上来都还要花费cost[i-1] 或者 cost[i-2] 位置的钱:

所以每次都取最小值,到达i位置:

dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]);

所以每次dp[i] 都是由前面两个阶梯里面其中花费最小的一次得来的;

3.初始化:

题目说在0位置和1阶梯位置都不需要花费,所以dp[0] = dp[1] =0;

4.填表方向:

跟前面一样,也是要得到前面的值,才能往后继续填表,所以填表方向是从左往右填表;

5.返回值:

根据例子,有三个阶梯的花费,就要返回dp[3] ,那么n个就要返回dp[n],所以为了不越界,就要每次开n+1个位置,能够遍历到dp[n]

代码编写:

class Solution {
public:int minCostClimbingStairs(vector<int>& cost) {int n=cost.size();vector<int> dp(n+1);for(int i=2;i<=n;i++){dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);}return dp[n];}
};

总结:

这一个小专题写起来完全一模一样,就是分析线性dp,然后考虑初始化和返回值即可;

4. 解码⽅法(medium)

题目意思还是很好懂的,就是有单独和双解码两种方式,单独解码,和跟前一个字符一起解码为一个字符,问一起有多少种解码方法

解析:

这里提供两种方法,第二种在第一种上的优化:

方法一:

1.状态表达式:

根据题目意思,表达dp[i]表示:以i位置为结尾,解码的总数;

2.状态转移方程:

所以dp[i] 分为两种情况下,分别加上解码成功下的上一个dp值;

这里求两个位置的解码和大于等于10,是因为只要s[i-1]这一位不为‘0’,就一定会大于10,否则就被解码成02、03这样就是错的;

3.初始化:

因为上面状态转移方程里面有i-2,所以循环要从n==2开始,所以要初始化dp[0]、dp[1]:

dp[0]=s[0]!='0';只要s的首字符不为0,那么就可以得到dp[0]=1;

dp[1]:

在if(s[0]!='0' && s[1]!='0') 那么说明都可以单独解码,dp[1]+=1;

在int t=(s[0]-'0')*10+(s[1]-'0');//前两个位置表示的数
        if(t>=10&&t<=26) dp[1]++; 说明可以双解码,就又是一种解码方式;

4.填表方向:

从左向右;

5.返回值:

返回最后一位dp[n-1] 表示n-1位置的解码总数;

编写代码:

方法一:

class Solution {
public:int numDecodings(string s) {if(s[0]=='0') return 0;int n=s.size();vector<int> dp(n);if(s[0]!='0') dp[0]=1;if(n==1) return dp[0];if(s[0]!='0'&&s[1]!='0') dp[1]+=1;int t=(s[0]-'0')*10+(s[1]-'0');//前两个位置表示的数if(t>=10&&t<=26) dp[1]++;for(int i=2;i<n;i++){if(s[i]!='0') dp[i]+=dp[i-1]; //处理单独编码的情况int t=(s[i-1]-'0')*10+(s[i]-'0');  //处理两个字符同时解码的情况if(t>=10&&t<=26) dp[i]+=dp[i-2];  }return dp[n-1];}
};

优化:

我们可以看到这里初始化和循环内代码十分冗余,那么想想有没有办法可以简化一下初始化呢:

细节问题:

那么只需要将dp表多开一个空间,然后让dp[1]这个位置表示的是原来的dp[0],那么就可以让现在dp[2]表示原来的dp[1]就可以把刚刚初始化dp[1]的那一大堆步骤放在循环内了;

现在我们给dp表多开了一个空间,就要考虑当前dp[0] 的位置填什么:

那么这个时候就要考虑循环内的dp[2],倘若dp[2]这个位置可以双解码:

说明dp[2] += dp[2-2]
即dp[2] += dp[0],如果这里dp[0]=0,那么就相当于没有加上,
所以dp[0]=1;

此时dp[1]就还是跟上面原来的dp[0]一样,查看dp[1]=s[0]!='0';

最后要处理的就是s字符串下标的问题,因为dp都往后移动了一位,所以遍历s的时候i都要-1:i-1

class Solution {
public:int numDecodings(string s) {if(s[0]=='0') return 0;int n=s.size();vector<int> dp(n+1);dp[0]=1; //保证后面的填表是正确的dp[1]=s[0]!='0';for(int i=2;i<=n;i++){if(s[i-1]!='0') dp[i]+=dp[i-1]; //处理单独编码的情况int t=(s[i-2]-'0')*10+(s[i-1]-'0');  //处理两个字符同时解码的情况if(t>=10&&t<=26) dp[i]+=dp[i-2];  }return dp[n];}
};

总结:

优化就是在普通解法下总结出来的,我们可以先尝试普通解法的思想,然后再去考虑优化,这样一步步来,肯定会成功的,加油!~

路径问题

5. 不同路径(medium)

题目意思很简单,就是从左上角走到左下角,一共有多少走法

解析:

1.状态表达式:

因为这一题是一个二维数组内求路径总数,所以确定位置就是要确定当前dp表的一个位置

dp[i][j]表示:以i,j结尾的位置的总路径总数;

2.状态转移方程:

这个位置可以由上和左方向走来,所以:
就是当前位置的路径数,就等于 上方向 和 左方向 两个方向走来的路径和

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

3.初始化:

由于再dp表原先[0,0]位置可能会存在越界的情况,所以我们要将整个dp表多加一列和一行,就是为了预防[i-1],[j-1]这种情况;

所以就要考虑这多加的一行一列需要初始化为什么:

由于再[1,1]这个位置也需要由上一步得到当前的路径数,显然我们是从[1,1]开始的,那么路径是就是1,那么只需要将dp[0][1]或者dp[1][0]任意一个位置设置成1即可满足条件;

4.填表方向:

根据状态转移方程可以知道,都是要明白前面的值,才能继续往后填,所以填表方向就是从左往右,从上往下;

5.返回值:

根据状态表达式,明白dp[m][n] 就是再[m,n]这个位置的的路径总数,所以返回dp[m][n]

编写代码:

class Solution {
public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m+1,vector<int>(n+1,0));dp[0][1]=1;for(int i=1;i<=m;i++)for(int j=1;j<=n;j++)dp[i][j]=dp[i-1][j]+dp[i][j-1];return dp[m][n];}
};

总结:

整体来说还是非常好写的,这种思路很顺滑,如果真是自己一步步思考出来的还是非常有成就感的

6. 不同路径II(medium)

题目跟上题一样就是多了一个障碍物,然后路径中有障碍的位置都不能算做一条路径

解析:

这题唯一跟上提不同的就是状态转移方程:

唯一的不同就是在考虑当前位置是否存在障碍物,如果是,那么当前位置的dp值就是0;否则dp就等于dp[i][j]=dp[i-1][j] + dp[i][j-1]

 

代码编写:

class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& ob) {int m=ob.size(),n=ob[0].size();vector<vector<int>> dp(m+1,vector<int>(n+1));dp[0][1]=1;for(int i=1;i<=m;i++)for(int j=1;j<=n;j++)if(ob[i-1][j-1]!=1) dp[i][j]=dp[i-1][j]+dp[i][j-1];return dp[m][n];}
};

总结:

如果真的自己能够绕出来,真的贼有成就感,加油,一定会成功的!!!

7. 礼物的最⼤价值(medium)

题目意思很简单,就是从左上角走到右下角,然后再某一条路径上的总和最大

解析:

1.状态表达式:

dp[i][j]表示:以i,j为结尾的位置上 , 珠宝的最大价值总和;

2.状态转移方程:

因为每次只能选取一条路径上的最大珠宝价值,所以当前位置dp[i][j]就是上方向 或者 左方向取最大值然后加上当前位置的珠宝价值:

 dp[i][j]=max(dp[i-1][j],dp[i][j-1])+frame[i-1][j-1];

3.初始化:

因为在dp[1][1]的位置上,当前位置的价值就只是最初始位置的珠宝价值,所以不需要外边界的值,那么外边界都初始化为0;

4.填表方向:

通过状态转移方程,可以知道只有把前面的值填完了,才能填当前的值,那么就是从左往右填,从上往下填;

5.返回值:

根据状态表达式,可以得到dp[m][n]表示在[m,n]位置结尾的最大珠宝总和;

代码编写:

class Solution {
public:int jewelleryValue(vector<vector<int>>& frame) {int m=frame.size(),n=frame[0].size();vector<vector<int>> dp(m+1,vector<int>(n+1));int ret=0;for(int i=1;i<=m;i++)for(int j=1;j<=n;j++)dp[i][j]=max(dp[i-1][j],dp[i][j-1])+frame[i-1][j-1];return dp[m][n];}
};

总结:

这题就是上面两题的变形,还是非常好想的,依旧是套着模板写题;

8. 下降路径最⼩和(medium)

题目意思很简单理解,就是每一行都选一个数,但是这个数只能是上一行的一个数的左中右三个方向下的一个数,然后最后求出直到最后一行的时候所有路径里面最小的和

解析:

1.状态表达式:

设置dp[i][j]表示:以i,j为结尾的时候,当前路径最小和;

2.状态转移方程:

这里状态转移方程就要考虑当前位置在边界情况下是否会越界的问题:

那么设置一个dp表,由状态表达式可以知道dp[i][j]表示:以i,j为结尾的时候,当前路径最小和;

那么当dp在第一行的时候,就要通过上面一行来求出最小值,但是这样会越界,就要多开一行,设置成0,来保证不会越界;这个时候,不但要多开一行,还要多开两列,将左右两列都设置成INT_MAX,因为本来这两列是不存在的,但是为了在遍历上一行的三个位置的时候会出现越界情况,所以,多开两列,设置成最大值,这样就不会出现越界和乱取值的情况,这样怎么取,都是在ma原数组里面的值;

所以状态转移方程就是:

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

通过上一行的三个位置取出最小值,然后加上当前位置的ma的大小;

3.初始化:

上面以及涉及到,就是将第一行全部初始化为0,左右两列都初始化为INT_MAX,为的就是数组不越界,和不乱取值

4.填表顺序:

根据状态转移方程可以看到,必须要知道上面的值,才能往下求,所以是从左往右,从上往下填表

5.返回值:

每条路径都会走到最后一行,那么只需要用ret来记录最后一行的最小值即可;

编写代码:

class Solution {
public:int minFallingPathSum(vector<vector<int>>& ma) {int m=ma.size(),n=ma[0].size();vector<vector<int>> dp(m+1,vector<int>(n+2));for(int i=0;i<=m;i++){dp[i][0]=INT_MAX;dp[i][n+1]=INT_MAX;}int ret=INT_MAX;for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){dp[i][j]=min(min(dp[i-1][j],dp[i-1][j-1]),dp[i-1][j+1])+ma[i-1][j-1];if(i==m) ret=min(dp[i][j],ret);}}return ret;}
};

总结:

只要画图一步步把每一步都分析清楚,那么就是按部就班的写代码就ok了

9. 最⼩路径和(medium)

题目很好理解,就是求出左上角到右下角的路径最小总和

解析:

这一题就不过多赘述,题目意思完全就是跟上面几题一模一样,唯一的不同就是初始化的不同:

如果这题我跟上面一样也全部都初始化为0,那么由状态转移方程就是:

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

每次都是在左边和上面去一个较小值,然后加上当前位置的gird数组的数字,那么可以现象,外边界全是0,那么遍历在第一行和第一列的时候,怎么会加上左边或者上面的值呢,看到都是加上最小的0了,所以这种初始化是不成立的;

那么就有另外一种办法,全部初始化为INT_MAX,那么对于dp[1][1]进行计算的时候,就是取
dp[0][1] 和 dp[1][0]里面最小的一个再加上grid[0][0],显然这是绝对不可以的,因为dp[1][1]这个位置就只是只应该有自己原本的那个数,所以dp[0][1] 和 dp[1][0]都应该初始化为0,其他位置都初始化为INT_MAX;

所以这一题就只有这一个初始化的位置需要注意;

代码编写:

class Solution {
public:int minPathSum(vector<vector<int>>& grid) {int m=grid.size(),n=grid[0].size();vector<vector<int>> dp(m+1,vector<int>(n+1,INT_MAX));dp[0][1]=0;for(int i=1;i<=m;i++)for(int j=1;j<=n;j++){dp[i][j]=min(dp[i][j-1],dp[i-1][j])+grid[i-1][j-1];cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;}return dp[m][n];}
};

总结:

写出一个动态规划的题目并不是一帆风顺,需要自己的独立思考和每一个位置不出现漏洞,所以对于每一步都要仔细的去分析分析在分析;

10. 地下城游戏(hard)

耐心读题,还是很简单的,骑士从左上角走到右下角,然后经过的格子如果是正数就加血,是负数就扣血,如果血被扣到0或者负数就直接死亡,返回最后救出公主的最少血量

解析:

1.状态表达式:

这题如果按照前面一样正着来求解肯定会很麻烦,我们可以先尝试一下:

每次都要考虑骑士的血量,并且我们并不知道骑士的初始血量,所以每次都要给一个初始血量后再出发,知道走下去时血量为空或者还有更优解才会停下来,所以从数组的[0,0]位置开始行走的话一定会失败的;那么问题来了,考虑骑士的最初血量,我们就可以正难则反,从骑士救出公主的那一刻开始往回走,直到走到[0,0]这个位置停下来得到最少的血量即可;

所以

dp[i][j]表示:以i,j为结尾的骑士所需要的最少血量;

2.状态转移方程:

这里考虑两种情况:

第一种就是当最后一个格子是负数的时候;

第二种就是最后一个格子是正数的时候;

说明如果最后一个格子是负数,就要考虑在进入最后一个格子之前拥有的血量是要至少大于这个格子扣除血量+1的,也就是说,经过最后一个格子了,至少还剩最后一滴血;

如果最后一个格子是正数,那么就只需要进入之前至少还剩一滴血就ok了;

那么就说明dp[i][j]=下面 和 右边 取min后 然后减去du[i][j]的值即可;

如果du[i][j] 为负值,那么就正好减后成正值;

如果du[i][j] 为正值:此时dp[i][j]>0

所以状态转移方程:

                int sum=min(dp[i+1][j],dp[i][j+1]);

                if(du[i][j]>0&&du[i][j]>=sum) dp[i][j]=1;

                else dp[i][j]=sum-du[i][j];

3.初始化:

根据上面的图和分析可以得出,为了在边界条件下不会越界和乱取值,只用初始化一个值即可就

dp[m][n-1]=1;

4.填表顺序:

这次填表顺序很不一样,因为我们是要从后往前遍历,一直得到dp[0][0],所以填表顺序就是从下往上,从右往左;

5.返回值:

根据状态表达式,返回dp[0][0] 即可表示在[0,0]位置骑士所需要的最少血量;

代码编写:

class Solution {
public:int calculateMinimumHP(vector<vector<int>>& du) {int m=du.size(),n=du[0].size();vector<vector<int>> dp(m+1,vector<int>(n+1,INT_MAX));dp[m][n-1]=1;for(int i=m-1;i>=0;i--){for(int j=n-1;j>=0;j--){int sum=min(dp[i+1][j],dp[i][j+1]);if(du[i][j]>0&&du[i][j]>=sum) dp[i][j]=1;else dp[i][j]=sum-du[i][j];}}return dp[0][0];}
};

总结:

独立解决一道困难题真的很帅好吧,xdm 给点鼓励~!!!

总结一下吧~总结不易,本章节对我的收获巨大,希望对你也是~!!!

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

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

相关文章

阿里云centos7.9服务器磁盘挂载,切换服务路径

项目背景 1、项目使用的服务器为阿里云centos7.9&#xff0c;默认的磁盘为vda&#xff0c;文件系统挂载在这个磁盘上&#xff0c;项目上使用的文件夹为/home/hnst/uploadPath 2、vda使用率已达到91% 3、现购置一块新的磁盘为vdb&#xff0c;大小为2T 目的 切换服务所使用的…

STM32问题集

这里写目录标题 一、烧录1、 Can not connect to target!【ST-LINK烧录】 一、烧录 1、 Can not connect to target!【ST-LINK烧录】 烧录突然 If the target is in low power mode, please enable “Debug in Low Power mode” option from Target->settings menu 然后就&…

Scala学习记录,case class,迭代器

case class case class创建的对象的属性是不可改的 创建对象&#xff0c;可以不用写new 自动重写&#xff1a;toString, equals, hashCode, copy 自动重写方法&#xff1a;toString,equals,hashCode,copy 小习一下 1.case class 的定义语法是什么 基本形式&#xff1a;case …

成都睿明智科技有限公司解锁抖音电商新玩法

在这个短视频风起云涌的时代&#xff0c;抖音电商以其独特的魅力迅速崛起&#xff0c;成为众多商家争夺的流量高地。而在这片充满机遇与挑战的蓝海中&#xff0c;成都睿明智科技有限公司犹如一颗璀璨的新星&#xff0c;以其专业的抖音电商服务&#xff0c;助力无数品牌实现从零…

阅读2020-2023年《国外军用无人机装备技术发展综述》笔记_技术趋势

目录 文献基本信息 序言 1 发展概况 2 重点技术发展 2.1 人工智能技术 2.1.1 应用深化 2.1.2 作战效能提升 2.2 航空技术 2.2.1螺旋桨设计创新 2.2.2 发射回收技术进步 2.3 其他相关技术 2.3.1 远程控制技术探 2.3.2 云地控制平台应用 3 装备系统进展 3.1 无人作…

LeetCode 86.分隔链表

题目&#xff1a; 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 思路&#xff1a; 代码&#xff1a; /*** Definiti…

SystemVerilog学习笔记(六):控制流

条件语句 条件语句用于检查块中的语句是否被执行。条件语句创建语句块。如果给出的表达式是 true&#xff0c;执行块中的语句集&#xff0c;如果表达式为 false&#xff0c;则 else 块语句将最后执行。 序号条件语句1.if2.if-else3.if-else ladder4.unique if5.unique0 if6.p…

SQL,力扣题目1127, 用户购买平台

一、力扣链接 LeetCode_1127 二、题目描述 支出表: Spending ---------------------- | Column Name | Type | ---------------------- | user_id | int | | spend_date | date | | platform | enum | | amount | int | ------------------…

【计算机网络】【传输层】【习题】

计算机网络-传输层-习题 文章目录 10. 图 5-29 给出了 TCP 连接建立的三次握手与连接释放的四次握手过程。根据 TCP 协议的工作原理&#xff0c;请填写图 5-29 中 ①~⑧ 位置的序号值。答案技巧 注&#xff1a;本文基于《计算机网络》&#xff08;第5版&#xff09;吴功宜、吴英…

群控系统服务端开发模式-应用开发-前端个人信息功能

个人信息功能我把他分为了3部分&#xff1a;第一部分是展示登录者信息&#xff1b;第二步就是登录者登录退出信息&#xff1b;第三部分就是修改个人资料。 一、展示登录者信息 1、优先添加固定路由 在根目录下src文件夹下route文件夹下index.js文件中&#xff0c;添加如下代码 …

Qwen2-VL:发票数据提取、视频聊天和使用 PDF 的多模态 RAG 的实践指南

概述 随着人工智能技术的迅猛发展&#xff0c;多模态模型在各类应用场景中展现出强大的潜力和广泛的适用性。Qwen2-VL 作为最新一代的多模态大模型&#xff0c;融合了视觉与语言处理能力&#xff0c;旨在提升复杂任务的执行效率和准确性。本指南聚焦于 Qwen2-VL 在三个关键领域…

Java面向对象高级2

1.代码块 2.内部类 成员内部类 public class Demo{public static void main(String[] args) {outer.inner innew outer().new inner();in.run();}}class outer{private String str"outer";public class inner{public void run(){String sstr;System.out.println(s);…

Elasticsearch 8.16:适用于生产的混合对话搜索和创新的向量数据量化,其性能优于乘积量化 (PQ)

作者&#xff1a;来自 Elastic Ranjana Devaji, Dana Juratoni Elasticsearch 8.16 引入了 BBQ&#xff08;Better Binary Quantization - 更好的二进制量化&#xff09;—— 一种压缩向量化数据的创新方法&#xff0c;其性能优于传统方法&#xff0c;例如乘积量化 (Product Qu…

androidstudio下载gradle慢

1&#xff0c;现象&#xff1a; 2&#xff0c;原因&#xff0c;国内到国外网址慢 3&#xff0c;解决方法&#xff1a;更改gradle-wrapper.properties #Wed Sep 26 20:01:52 CST 2018 distributionBaseGRADLE_USER_HOME distributionPathwrapper/dists zipStoreBaseGRADLE_USER…

浅谈:基于三维场景的视频融合方法

视频融合技术的出现可以追溯到 1996 年 , Paul Debevec等 提出了与视点相关的纹理混合方法 。 也就是说 &#xff0c; 现实的漫游效果不是从摄像机的角度来看 &#xff0c; 但其仍然存在很多困难 。基于三维场景的视频融合 &#xff0c; 因其直观等特效在视频监控等相关领域有着…

探索Python的HTTP利器:Requests库的神秘面纱

文章目录 **探索Python的HTTP利器&#xff1a;Requests库的神秘面纱**一、背景&#xff1a;为何选择Requests库&#xff1f;二、Requests库是什么&#xff1f;三、如何安装Requests库&#xff1f;四、Requests库的五个简单函数使用方法1. GET请求2. POST请求3. PUT请求4. DELET…

【算法一周目】双指针(2)

目录 有效三角形的个数 解题思路 C代码实现 和为s的两个数字 解题思路 C代码实现 三数之和 解题思路 C代码实现 四数之和 解题思路 C代码实现 有效三角形的个数 题目链接&#xff1a;611. 有效三角形的个数题目描述&#xff1a;给定一个包含非负整数的数组nums&…

基于Python的网上银行综合管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

C++编程技巧与规范-类和对象

类和对象 1. 静态对象的探讨与全局对象的构造顺序 静态对象的探讨 类中的静态成员变量(类类型静态成员) 类中静态变量的声明与定义&#xff08;类中声明类外定义&#xff09; #include<iostream> using namespace std;namespace _nmspl {class A{public:A():m_i(5){…

边缘的检测

边缘检测效果&#xff0c;是一种用于突出图像中的边缘&#xff0c;使物体的轮廓更加明显的图像处理技术&#xff0c;边缘检测的主要目的是找到图像中亮度变化显著的区域&#xff0c;这些区域通常对应于物体的边界&#xff0c;边缘检测相当于利用 Shader 代码自动给屏幕图像进行…