二刷 动态规划

news2024/10/7 8:29:57

什么是动态规划 Dynamic Programming DP

如果某一问题有很多重叠子问题,使用动态规划时最有效的

动态规划中每一个状态是由上一个状态推导出来的。

动规五部曲

1.确定dp数组以及下标的含义

2.确定递归公式

3.dp数组如何初始化

4.确定遍历顺序

5.举例推导dp数组


509.斐波那契数

1.确定dp数组和下标的含义

dp[i]:第i个数的斐波那契数值是dp[i]

2.确定递推公式

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

3.dp数组如何初始化

dp[0] = 0;

dp[1]=  1

4.确定遍历顺序

dp[i]依赖dp[i-1],dp[i-2],因此是从前向后

5.举例推导

0 1 1 2 3 5 8 13

class Solution {
public:
    int fib(int n) {
        //如果是0,1,直接返回
        if(n <= 1) return n;
        //创建dp数组
        vector<int> dp(n+1);
        //初始化
        dp[0] = 0;
        dp[1] = 1;
        for (int i = 2; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];

    }
};

70.爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

  • 输入: 2
  • 输出: 2
  • 解释: 有两种方法可以爬到楼顶。
    • 1 阶 + 1 阶
    • 2 阶

1.确定dp数组及下标含义

dp[i]:爬上i楼有dp[i]种方法

2.确定递推公式

第一层有一种方法

第二层有两种方法

第一层跨两步到第三层;第二层跨一步到第三层;

所以第三层楼梯的状态可以由第二层楼梯和到第一层楼梯的状态推导出来

dp[i-1],上i-1层楼梯,有dp[i-1]种方法,再一步跳一个台阶到dp[i]

dp[i-2],上i-2层楼梯,有dp[i-2]种方法,再一步跳两个台阶就是dp[i]。

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

3.dp数组初始化

dp[1] = 1

dp[2] = 2

4.确定遍历顺序

从前向后

5.模拟

class Solution {
public:
    int climbStairs(int n) {
        if ( n <= 1) return n;
        vector<int> dp(n+1);
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
};

746. 使用最小花费爬楼梯

给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。

你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

请你计算并返回达到楼梯顶部的最低花费。

1.确定dp数组和下标含义

dp[i]:到达i楼层的最低花费是dp[i]

2.确定递推公式

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

dp[i] = dp[i-2] + cost[i -2]

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

3.初始化

到达第0和第1台阶不需要花费体力

dp[0] = 0;

dp[1] = 0;

4.遍历顺序

从前向后

5.模拟

此处的n是cost.size()

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

62.不同路径

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

机器人从00出发到m-1,n-1

1.确定dp数组和下标含义

dp[i][j]:从00出发到ij有dp[i][j]条不同的路径

2.确定递推公式

只有两个方向能来

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

3.初始化

for  dp[i][0] = 1

for  dp[0][j] = 1

4.遍历顺序

从左到右一层一层遍历

注意最后一个点是m-1,n-1

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

63. 不同路径 II

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

思路:

1.确定dp数组和下标含义

dp[i][j]:从00到m-1,n-1有dp[i-1][j-1]条路径

2.确定递推公式

没有障碍情况下

if(obstacleGrid[i][j] == 0)

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

3.确定初始化

没有障碍才能为1

4.左上到右下

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        int m = obstacleGrid.size();
        int n = obstacleGrid[0].size();
        //起点或终点有障碍物,直接返回0;
        if (obstacleGrid[0][0] == 1 || obstacleGrid[m-1][n-1] == 1) return 0;
        vector<vector<int>> dp(m, vector<int>(n, 0));
        // 初始化,没有障碍物才能为1,遇到障碍物就为0
        for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) dp[i][0] = 1;
        for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) dp[0][j] = 1; 
        //遍历,遇到障碍物就跳过
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (obstacleGrid[i][j] == 1) continue;
                dp[i][j] = dp[i-1][j] + dp[i][j-1];
            }
        }
        return dp[m-1][n-1];
    }
};

343. 整数拆分

给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。

示例 1:

  • 输入: 2
  • 输出: 1
  • 解释: 2 = 1 + 1, 1 × 1 = 1。

1.确定dp数组和下标的含义

dp[i]:正整数i划分后得到的最大乘积

2.确定递推公式

从1遍历j,

将i划分为两个数 :dp = j*(i-j)

继续划分:j*dp[i-j]

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

3.初始化

dp[2] = 1

4.递归顺序

从前向后

class Solution {
public:
    int integerBreak(int n) {
        vector<int> dp(n + 1);
        dp[2] = 1;
        for (int i = 3; i <= n; i++) {
            //i/2:一般乘积最大 是中间的数
            for (int j = 1; j <= i/2; j++) {
                //j * (i-j)表示分成两个数字;j*dp[i - j]表示分成两个以上数字
                dp[i] = max(dp[i], max(j * (i - j), j * dp[i - j]));
            }
        }
        return dp[n];
    }
};

96.不同的二叉搜索树

给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?

1.确定dp[i]数组及下标的含义

dp[i]:以1-i为节点组成的二叉搜索树由dp[i]种

2.确定递推公式

n=3时

元素1为头节点搜索树的数量 = 右子树有2个元素的搜索树数量*左子树有0个元素的搜索树数量

元素2为头结点搜索树的数量 = 右子树有1个元素的搜索树数量*左子树有1个元素的搜索树数量

元素3为头结点搜索树的数量 = 右子树有0个元素的搜索树数量*左子树有2个元素的搜索树数量

有两个元素的搜索树数量是dp[2]

有1个元素的搜索树数量是dp[1]

有0个元素的搜索树数量是dp[0]

dp[3] = dp[2]*dp[0] + dp[1]*dp[1]+dp[0]*dp[2]

dp[i] += dp[以j为头结点左子树节点数量]*dp[以j为头结点右子树节点数量]

j相当于头节点的元素,从1遍历到i为止

递推公式:dp[i] += dp[j - 1]*dp[i-j]

3.初始化

dp[0] = 1;

4.遍历顺序

i是依靠i之前的节点数的状态

for(int i = 1; i<=n; i++) {

        for (int j = 1;j <= i;j++) {

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

}

5.模拟

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

198.打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

  • 示例 1:
  • 输入:[1,2,3,1]
  • 输出:4

1.确定dp[i]数组及下标的含义

dp[i]:考虑下标i以内的房屋,偷窃的最高金额

2.确定递推公式

如果偷第i间房,找出i-2以内的房屋最多可偷的金额+这间房的金额:dp[i] = dp[i - 2] + nums[i]

如果不偷第i间房,则可以考虑第i-1间房,但不一定就要偷i-1:dp[i] = dp[i-1]

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

3.初始化

dp[0] = nums[0];

dp[1] = max(nums[0], nums[0]);

4.遍历顺序

从前往后

  

注意要当nums只有一个时,直接返回这个即可。

class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() == 1) return nums[0];
        vector<int> dp(nums.size());
        dp[0] = nums[0];
        dp[1] = max(nums[0], nums[1]);
        for (int i = 2; i < nums.size(); i++) {
            dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
        }
        return dp[nums.size() - 1];
    }
};

213.打家劫舍II

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。

给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,能够偷窃到的最高金额。

示例 1:

  • 输入:nums = [2,3,2]

  • 输出:3

1.确定dp数组和下标的含义

dp[i]:i房屋以内的房屋最大的偷窃金额是dp[i]

2.确定递推公式

考虑两种情况:只包含头和只包含尾分别考虑,取最大值

class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() == 1) return nums[0];
        int result1 = robRange(nums, 0, nums.size() - 2);
        int result2 = robRange(nums, 1, nums.size() - 1);
        return max (result1, result2);
    }

    int robRange(vector<int>& nums, int start, int end) {
    vector<int> dp(nums.size());
    dp[start] = nums[start];
    dp[start + 1] = max(nums[start], nums[start + 1]);
    for (int i = start + 2; i <= end; i++) {
        dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
    }
    return dp[end];
}
};

121. 买卖股票的最佳时机

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

  • 示例 1:

  • 输入:[7,1,5,3,6,4]

  • 输出:5

1.确定dp[i]及下标的含义

dp[i][0]:第i天不持有股票

dp[i][1]:第i天持有股票

2.递推公式

dp[i][0]:第i天不持有股票有两种情况

第i-1天就不持有:dp[i - 1][0]

第i-1天持有,第i天卖出:dp[i - 1][1] + prices[i]

求最大值

dp[i][1]:第i天持有股票有两种情况

第i-1天就持有:dp[i - 1][1]

第i-1天不持有,第i天买入:- prices[i]

---这里 只买一次,第一次买股票 手头现金一定是0,所以直接-prices[i]

求最大值

3.初始化

dp[0][0] = 0

dp[0][1] = -prices[0]

4.遍历顺序

5.模拟

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.size() == 0) return 0;
        vector<vector<int>> dp(prices.size(),vector<int>(2));
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        for (int i = 1; i < prices.size(); i++) {
            dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
            dp[i][1] = max(-prices[i], dp[i - 1][1]);
        }
    //最后一定是选择不持有股票赚的多
        return dp[prices.size() - 1][0];
    }
};

122.买卖股票的最佳时机II

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

  • 示例 1:

  • 输入: [7,1,5,3,6,4]

  • 输出: 7

1.确定dp[i]数组及下标的含义

dp[i][0]:不持有股票

dp[i][1]:持有股票

2.确定递推公式

dp[i][0]:第i天不持有股票

第i-1天就不持有,dp[i-1][0]

第i-1天持有,第i天卖出:dp[i - 1][1] + prices[i]

dp[i][1]:第i天持有股票

第i-1天就持有:dp[i-1][1]

第i-1天不持有,第i天买入:dp[i - 1][0] -prices[i]

唯一不同点:买卖多次股票,买入的时候手头现金非0

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int len = prices.size();
        vector<vector<int>> dp(len, vector<int>(2, 0));
        dp[0][0] = 0;
        dp[0][1] = -prices[0];
        for (int i = 1; i < len; i++) {
            dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
        }
        return dp[len - 1][0];
    }
};

647. 回文子串

给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。

具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例 1:

  • 输入:"abc"
  • 输出:3
  • 解释:三个回文子串: "a", "b", "c"

1.确定dp[i]及下标的含义

dp[i][j]:[i,j]区间内是否是回文串

2.递推公式

s[i]==s[j]分为三种情况

a, aa都属于i-j<=1,相差一个距离

相差多个距离ababa,要根据dp[i+1][j-1]是否满足回文串了

3.初始化

初始都为false

4.遍历顺序

因为dp[i][j]依赖于dp[i+1][j-1] 所以从下往上从左往右

class Solution {
public:
    int countSubstrings(string s) {
        int len = s.size();
        int result = 0;
        vector<vector<bool>> dp(len, vector<bool>(len, false));
        for (int i = len - 1; i >= 0; i--) {
            for (int j = i; j < len; j++) {//j从i开始
                if (s[i] == s[j]) {
                    if (j - i <= 1) {
                        result++;
                        dp[i][j] = true;
                    } else if (dp[i + 1][j - 1]) {
                        result++;
                        dp[i][j] = true; 
                    }
                }
            }
        }
        return  result;
    }
};

516.最长回文子序列

给定一个字符串 s ,找到其中最长的回文子序列,并返回该序列的长度。可以假设 s 的最大长度为 1000 。

示例 1: 输入: "bbbab" 输出: 4 一个可能的最长回文子序列为 "bbbb"。

示例 2: 输入:"cbbd" 输出: 2 一个可能的最长回文子序列为 "bb"。

回文子序列不连续

1.确定dp[i]数组和下标

dp[i][j]:字符串s在[i,j]范围里最长的回文子序列的长度是dp[i][j]

2.确定递推公式

如果s[i] == s[j] ,dp[i][j] = dp[i+1][j-1]+2

如果s[i] != s[j], dp[i][j] = max(dp[i+1][j], dp[i][j-1]);看看分别加入s[i]、s[j]哪一个可以组成最长的回文子序列。

3.初始化

i=j相同的时候,初始化为1

其他默认为0

4.遍历顺序

dp[i][j]依赖于dp[i+1][j-1],从下往上,从左往右

内层循环:for(j = i+1)原因是,j必须大于i,并且j=i已经初始化了

class Solution {
public:
    int longestPalindromeSubseq(string s) {
        vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));
        //i=j的时候,为1
        for(int i = 0; i < s.size(); i++) dp[i][i] =1;
        for(int i = s.size() - 1; i >= 0; i--) {
            for (int j = i + 1; j < s.size(); j++) {
                if (s[i] == s[j]) {
                    dp[i][j] = dp[i + 1][j - 1] + 2;
                }else if (s[i] != s[j]) {
                    dp[i][j] = max(dp[i+1][j], dp[i][j-1]);
                }
            }
        }
        return dp[0][s.size() - 1];
    }
};

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

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

相关文章

软件开发案例参考

前言&#xff1a;基于平台现有需求进行新功能模块开发与实现&#xff0c;以下内容为部分源码解析&#xff0c;仅提供一些思路参考&#xff0c;不予以客观指导&#xff0c;毕竟条条大路通罗马嘛&#xff1b; 语言&#xff1a;C# 工具&#xff1a;visual studio 2017/visual st…

【unity实战】在Unity中使用有限状态机制作一个敌人AI

最终效果 文章目录 最终效果前言有限状态机的主要作用和意义素材下载逻辑图敌人动画配置优雅的代码文件目录状态机代码定义敌人不同状态切换创建敌人效果更多的敌人参考源码完结 前言 有限状态机以前的我嗤之以鼻&#xff0c;现在的我逐帧分析。其实之前我就了解过有限状态机&…

晚上睡觉要不要关路由器?一语中的

前言 前几天小白去了一个朋友家&#xff0c;有朋友说&#xff1a;路由器不关机的话会影响睡眠吗&#xff1f; 这个影响睡眠嘛&#xff0c;确实是会的。毕竟一时冲浪一时爽&#xff0c;一直冲浪一直爽……刷剧刷抖音刷到根本停不下来&#xff0c;肯定影响睡眠。 所以晚上睡觉要…

PCL 点云最小图割(前景、背景点云提取)

点云最小图割 一、概述1.1 概念1.2 算法原理二、代码示例三、运行结果🙋 结果预览 一、概述 1.1 概念 最小图割算法(pcl::MinCutSegmentation):是一种基于图论的对象分割方法,主要用于点云数据的处理和分析。该算法将点云数据表示为一个图结构,其中点云中的点作为图的节…

【SkiaSharp绘图14】SKCanvas方法详解(三)URL注释、按顶点绘制、 是否裁切区域之外、旋转、缩放、倾斜、平移、保存/恢复画布

文章目录 SKCanvas方法DrawUrlAnnotation 绘制URL注释DrawVertices 按顶点绘制Flush 立即绘制QuickReject 判断区域是否在裁切区域之外ResetMatrix重置矩阵Restore、RestoreToCountRotateDegrees按角度旋转画布RotateRadians按弧度旋转画布SaveLayer保存并新建图层Scale 缩放画…

二叉树(2)

二叉树的销毁 分为三个部分的销毁&#xff1a;根节点&#xff0c;左子树和右子树 void TreeDestory(BTNode* root) {if(rootNULL)return;TreeDestory(root->left);TreeDestory(root->right);free(root);rootNULL; }层序遍历&#xff08;上一层带下一层&#xff09; ty…

nginx如何解决惊群效应

什么是惊群效应 惊群效应&#xff08;thundering herd&#xff09;是指多进程&#xff08;多线程&#xff09;在同时阻塞等待同一个事件的时候&#xff08;休眠状态&#xff09;&#xff0c;如果等待的这个事件发生&#xff0c;那么他就会唤醒等待的所有进程&#xff08;或者线…

web权限到系统权限 内网学习第一天 权限提升 使用手工还是cs???msf可以不??

现在开始学习内网的相关的知识了&#xff0c;我们在拿下web权限过后&#xff0c;我们要看自己拿下的是什么权限&#xff0c;可能是普通的用户权限&#xff0c;这个连添加用户都不可以&#xff0c;这个时候我们就要进行权限提升操作了。 权限提升这点与我们后门进行内网渗透是乘…

用AI,每天创作200+优质内容,2分钟教会你操作!

前段时间发布了这篇“寻找爆款文案及标题的9大渠道&#xff0c;直接搬运都能搞流量&#xff01;”&#xff0c;里面我讲到如何寻找爆款标题。最近不少朋友问我&#xff0c;如何创作这个标题相关的内容。 多数平台都有风控规则&#xff0c;有些平台内容也会有字数要求。为了让大…

【D3.js in Action 3 精译】1.2.2 可缩放矢量图形(三)

当前内容所在位置 第一部分 D3.js 基础知识 第一章 D3.js 简介 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知 1.2.1 HTML 与 DOM1.2.2 SVG - 可缩放矢量图形 ✔️ 第一部分第二部分【第三部分】✔️ 1.2.3 Canvas 与 WebGL&#xff08;精译中 ⏳&#xff09;1.2.4 C…

10.8K star!史上最强Web应用防火墙雷池WAF

长亭雷池SafeLine是长亭科技耗时近 10 年倾情打造的WAF(Web Application Firewall)&#xff0c; 一款敢打出口号 “不让黑客越雷池一步” 的 WAF&#xff0c;愿称之为史上最强的一款Web应用防火墙&#xff0c;足够简单、足够好用、足够强的免费且开源的 WAF&#xff0c;基于业…

全球首款商用,AI为视频自动配音配乐产品上线

近日&#xff0c;海外推出了一款名为Resona V2A的产品&#xff0c;这是全球首款商用视频转音频 (V2A) 技术产品。这项突破性技术利用AI&#xff0c;仅凭视频数据即可自动生成高质量、与上下文相关的音频&#xff0c;包括声音设计、音效、拟音和环境音&#xff0c;为电影制作人、…

单向链表结构

链表结构简介 链表结构是一种用比较特殊的数据结构类型&#xff0c;它也是线性数据结构中的一种&#xff0c;但是与栈结构等线性数据结构不同&#xff0c;它的内部结构并不是一个简单的存储空间&#xff0c;而是一个带有指向性质的单元。要理解链表结构要弄清楚两个问题&#x…

react_后台管理_项目

目录 1.运行项目 2. 项目结构 ①项目顶部导航栏 ②项目左侧导航栏 ③主页面-路由切换区 本项目使用的是 reacttsscss 技术栈。 1.运行项目 在当前页面顶部下载本项目&#xff0c;解压后使用编辑器打开&#xff0c;然后再终端输入命令&#xff1a; npm i 下载依赖后&am…

使用Python绘制动态螺旋线:旋转动画效果

文章目录 引言准备工作前置条件 代码实现与解析导入必要的库初始化Pygame绘制螺旋线函数主循环 完整代码 引言 螺旋线是一个具有美学和数学魅力的图形。通过编程&#xff0c;我们可以轻松创建动态旋转的螺旋线动画。在这篇博客中&#xff0c;我们将使用Python和Pygame库来实现…

【python脚本】批量检测sql延时注入

文章目录 前言批量检测sql延时注入工作原理脚本演示 前言 SQL延时注入是一种在Web应用程序中利用SQL注入漏洞的技术&#xff0c;当传统的基于错误信息或数据回显的注入方法不可行时&#xff0c;例如当Web应用进行了安全配置&#xff0c;不显示任何错误信息或敏感数据时&#x…

解决卡顿发热,超帧技术焕发中重载游戏动力

近几年&#xff0c;中国手游市场规模不断扩大&#xff0c;开发者通过在画面、玩法等方面的持续创新和打磨&#xff0c;推出更加精品化的产品。然而愈发精美的画质和复杂的玩法&#xff0c;也给硬件带来超高的负载&#xff0c;导致玩家在游戏过程中&#xff0c;频繁出现掉帧卡顿…

动态规划算法,完全零基础小白教程!不是计算机的都能学会!万字吐血详解。

目录 一、动态规划算法概念 题一 1、算法解析 1&#xff09;确定状态&#xff1a; ​2&#xff09;状态转移方程&#xff1a; ​3&#xff09;初始化&#xff1a; 4&#xff09;填表顺序&#xff1a; 5&#xff09;返回值&#xff1a; 2、代码 题二 1、算法解析 1、确…

你喜欢波段交易吗?

波段交易的核心在于精准捕捉市场中的长期趋势波动&#xff0c;以实现更为稳健的收益。与剥头皮和日内交易不同&#xff0c;波段交易者更倾向于持有交易头寸数日乃至数周&#xff0c;以更宽广的视角把握市场动态。 这种交易方式的优势在于&#xff0c;它降低了对即时市场反应的…

C - Popcorn(abs358)

题意&#xff1a;有n个摊子&#xff0c;m个爆米花&#xff0c;想花费最少去的店铺买到所有的口味的爆米花&#xff0c;找到每一列都为‘o’的最少行数。 分析&#xff1a;用dfs寻找最少路径 #include<bits/stdc.h> using namespace std; typedef long long ll; char x;…