动态规划:买卖股票系列

news2024/11/28 2:41:49

目录

1. 买卖股票的最佳时机1-只能买卖一次(LeetCode121)

解法1:暴力解法

解法2:贪心算法

解法3:动态规划

2. 买卖股票的最佳时机2-可以买卖多次(LeetCode122)

解法1:贪心算法

解法2:动态规划

3. 买卖股票的最佳时机3-最多买卖两次(LeetCode123) 

4. 买卖股票的最佳时机4-最多买卖k次(LeetCode188) 

5. 买卖股票的最佳时机含冷冻期-买卖多次,卖出有一天冷冻期(LeetCode309) 

6. 买卖股票的最佳时机含手续费-买卖多次,每次有手续费(LeetCode714) 


前言

  • 所有的股票问题 都可以使用 动态规划 来求解(动态规划是求解股票问题的正规解法)
  • 部分的股票问题 可以使用 贪心算法 来求解(贪心往往比动态规划更巧妙更好用,但是贪心只能解决部分场景) 

1. 买卖股票的最佳时机1-只能买卖一次(LeetCode121)

题目描述:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/description/

解法1:暴力解法

解题思路

  • 第一层for循环:遍历买股票的位置(区间起点)
  • 第二层for循环:遍历卖股票的位置(区间终点)
#include <iostream>
using namespace std;
#include <vector>

class Solution
{
public:
    int maxProfit(vector<int>& prices)
    {
        int result = 0;
        // 第一层for循环:遍历买股票的位置(区间起点)
        for (int i = 0; i < prices.size(); i++)
        {
            // 第二层for循环:遍历卖股票的位置(区间终点)
            for (int j = i + 1; j < prices.size(); j++)
            {
                result = max(result, prices[j] - prices[i]);  // 打擂法求最大值
            }
        }
        return result;
    }
};

int main()
{
    //vector<int> prices{ 7,1,5,3,6,4 };  // 5
    vector<int> prices{ 7,6,4,3,1 };  // 0

    Solution s;
    int ans = s.maxProfit(prices);

    cout << ans << endl;

    system("pause");
    return 0;
}

复杂度分析

  • 时间复杂度:O(n^2)   LeetCode提交超时  
  • 空间复杂度:O(1)      无需额外的辅助空间

解法2:贪心算法

解题思路:由于股票就买卖一次,因此贪心思路为"取最左最小值,取最右最大值",得到的差值就是最大利润。 

#include <iostream>
using namespace std;
#include <vector>

class Solution
{
public:
	int maxProfit(vector<int>& prices)
	{
		int low = INT_MAX;
		int result = 0;
		for (int i = 0; i < prices.size(); i++)
		{
			low = min(low, prices[i]);
			result = max(result, prices[i] - low);
		}
		return result;
	}
};

int main()
{
	vector<int> prices{ 7,1,5,3,6,4 };  // 5
	//vector<int> prices{ 7,6,4,3,1 };  // 0

	Solution s;
	int ans = s.maxProfit(prices);

	cout << ans << endl;

	system("pause");
	return 0;
}

复杂度分析

  • 时间复杂度O(n)   需要从前向后遍历prices数组
  • 空间复杂度:O(1)   需要辅助变量low,为常数级的空间

解法3:动态规划

解题思路:动态规划五部曲

  • Step1:确定dp数组(一维)/dp表格(二维)、下标的含义
    • dp[i][0]:第i天不持有股票,所得最多现金
      • 注意:第i天不持有股票,并不表示第i天一定卖出股票,有可能是前面卖出股票,第i天仅仅是维持卖出股票的状态
    • dp[i][1]:第i天持有股票,所得最多现金
      • 注意:第i天持有股票,并不表示第i天一定买入股票,有可能是前面买入股票,第i天仅仅是维持买入股票的状态
  • Step2:确定递推公式
    • dp[i][0]:第i天不持有股票 可以由两个状态推导出来
      • 第i-1天不持有股票,第i天保持现状 → 所得现金就是昨天不持有股票的所得现金 dp[i - 1][0]
      • 第i-1天持有股票,第i天卖出股票 → 所得现金就是按照今天股票价格卖出后所得现金 dp[i - 1][1] + prices[i]
    • dp[i][1]:第i天持有股票 可以由两个状态推导出来
      • 第i-1天不持有股票,第i天买入股票 → 所得现金就是买入今天的股票后所得现金 dp[i-1][0]-prices[i] → -prices[i]
        • 由于本题的限制条件为买卖一次,第i天买入股票表明前面均不能买入,因此前面不会有任何收益,即dp[i-1][0]=0
      • 第i-1天持有股票,第i天保持现状 → 所得现金就是昨天持有股票的所得现金 dp[i-1][1]
  • Step3:初始化dp数组
    • 从递推公式可以看出,i是由i-1推导而来,因此需要初始化第一个元素
    • dp[0][0]:第0天不持有股票,所得最多现金为0
    • dp[0][1]:第0天持有股票(表明买入股票),所得最多现金为-prices[0]
  • Step4:确定遍历顺序
    • 从递推公式可以看出,i是由i-1推导而来,因此需要从前向后遍历 
  • Step5:打印dp数组(调试) 
#include <iostream>
using namespace std;
#include <vector>

class Solution
{
public:
    int maxProfit(vector<int>& prices) 
    {
        // Step3:初始化dp数组
        vector<vector<int>> dp(prices.size(), vector<int>(2,0));
        dp[0][0] = 0;
        dp[0][1] = -prices[0];

        // Step4:确定遍历顺序
        for (int i = 1; i < prices.size(); i++)
        {
            // Step2:确定递推公式
            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]; // 不持有股票状态 一定比 持有股票状态 所得金钱多
    }
};

int main()
{
    //vector<int> prices{ 7,1,5,3,6,4 };  // 5
    vector<int> prices{ 7,6,4,3,1 };  // 0

    Solution s;
    int ans = s.maxProfit(prices);

    cout << ans << endl;

    system("pause");
    return 0;
}

手动模拟dp数组的执行过程:prices = [ 7,1,5,3,6,4 ]
       dp[i][0]    dp[i][1]
i=0       0            -7
i=1       0            -1
i=2       4            -1
i=3       4            -1
i=4       5            -1
i=5       5            -1 

2. 买卖股票的最佳时机2-可以买卖多次(LeetCode122)

题目描述:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/

题目简述

  • 允许多次买卖
  • 任何时候 最多 只能持有 一股 股票(即必须在再次购买前出售掉之前的股票) 

解法1:贪心算法

解题思路

  • 收集每天的正利润(局部最优) → 最大利润(全局最优)
  • 收集正利润的区间   → 股票买卖的区间(非题目要求,并不关心哪一天买入,哪一天卖出)
#include <iostream>
using namespace std;
#include <vector>

class Solution {
public:
    int maxProfit(vector<int>& prices) 
    {
        // Step0:定义变量(准备工作)
        int max_profit = 0;     // 存储最终结果(最大利润)
        int cur_profit = 0;     // 存储每天的正利润

        for (int i = 1; i < prices.size(); i++)
        {
            // Step1:计算每天的正利润
            cur_profit = prices[i] - prices[i - 1];

            // Step2:更新最终结果  三种方式(由简到难)
            max_profit += max(cur_profit, 0);            // max操作   
            // max_profit += cur_profit > 0 ? cur_profit : 0;   // 三目运算符
            // if (cur_profit > 0) max_profit += cur_profit;    // if语句
        }
        return max_profit;
    }
};

int main()
{
    vector<int> prices{ 7,1,5,3,6,4 };
    //vector<int> prices{ 1,2,3,4,5 };
    //vector<int> prices{ 7,6,4,3,1 };

    Solution s;
    int ans = s.maxProfit(prices);

    cout << ans << endl;

    system("pause");
    return 0;
}

示例1(非单调):    7       1       5         3        6        4
正利润:                    -6       4       -2        3       -2        →  最大利润为4+3=7
正利润区间:                    [1,2]              [3,4]               →  [1,2]表示第1天买入,第2天卖出(天数从0开始计数)
买卖方式:第1天买入,第2天卖出;第3天买入,第4天卖出  此时可以获得最大利润
        
示例2(单调递增):  1       2      3      4      5
正利润:                     1       1      1      1       →  最大利润为1+1+1+1=4
正利润区间:            [0,1]   [1,2]  [2,3]  [3,4]
买卖方式1:第0天买入,第1天卖出;第1天买入,第2天卖出;第2天买入,第3天卖出;第3天买入,第4天卖出  此时可以获得最大利润
买卖方式2(合并连续区间):第0天买入,第4天卖出  此时可以获得最大利润
                
示例3(单调递减):  7        6        4        3        1
正利润:                     -1        -1       -1      -2           →  最大利润为0
正利润区间:无
买卖方式:不参与交易 

复杂度分析

  • 时间复杂度:O(n) 
  • 空间复杂度:O(1)

注意事项

  • 易错点1:max_profit初始化为0?还是初始化为INT_MIN?
    • max_profit应该初始化0,此时即便没有参与交易,利润应该为0,而不是负无穷
  • 易错点2:i从0开始?还是从1开始?
    • i应该从1开始,因为第0天没有利润,至少要第1天才会有利润,正利润的序列比股票序列少一天! 

解法2:动态规划

解题思路

  • Step1:确定dp数组(一维)/dp表格(二维)、下标的含义
    • dp[i][0]:第i天不持有股票,所得最多现金
    • dp[i][1]:第i天持有股票,所得最多现金
  • Step2:确定递推公式
    • dp[i][0]:第i天不持有股票 可以由两个状态推导出来
      • 第i-1天不持有股票,第i天保持现状 → 所得现金就是昨天不持有股票的所得现金 dp[i - 1][0]
      • 第i-1天持有股票,第i天卖出股票 → 所得现金就是按照今天股票价格卖出后所得现金 dp[i - 1][1] + prices[i]
    • dp[i][1]:第i天持有股票 可以由两个状态推导出来
      • 第i-1天不持有股票,第i天买入股票 → 所得现金就是买入今天的股票后所得现金 dp[i-1][0]-prices[i]
        • 注意:这是本题与"买卖股票的最佳时机-只能买卖一次"的唯一区别(买入股票时,可能会有之前买卖的利润)
        • 由于本题能够买卖多次,尽管第i-1天不持有股票,但是前面仍然可能发生过交易,导致前面可能会产生收益,即dp[i-1][0]不一定等于0
      • 第i-1天持有股票,第i天保持现状 → 所得现金就是昨天持有股票的所得现金 dp[i-1][1]
  • Step3:初始化dp数组
    • 从递推公式可以看出,i是由i-1推导而来,因此需要初始化第一个元素
    • dp[0][0]:第0天不持有股票,所得最多现金为0
    • dp[0][1]:第0天持有股票(表明买入股票),所得最多现金为-prices[0]
  • Step4:确定遍历顺序
    • 从递推公式可以看出,i是由i-1推导而来,因此需要从前向后遍历 
  • Step5:打印dp数组(调试)
#include <iostream>
using namespace std;
#include <vector>

class Solution
{
public:
	int maxProfit(vector<int>& prices)
	{
        vector<vector<int>> dp(prices.size(), vector<int>(2, 0));
        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(dp[i - 1][0] - prices[i], dp[i - 1][1]);  // 唯一区别
        }
        return dp[prices.size() - 1][0];  // 不持有股票状态 一定比 持有股票状态 所得金钱多
	}
};

int main()
{
    vector<int> prices{ 1,2,3,4,5 };  // 4
    //vector<int> prices{ 7,6,4,3,1 };  // 0

    Solution s;
    int ans = s.maxProfit(prices);

    cout << ans << endl;

	system("pause");
	return 0;
}

 复杂度分析

  • 时间复杂度:O(n) 
  • 空间复杂度:O(n)

3. 买卖股票的最佳时机3-最多买卖两次(LeetCode123) 

题目描述:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/description/

解题思路: 动态规划五部曲

  • Step1:确定dp数组(一维)/dp表格(二维)、下标的含义
    • dp[i][0]:第i天 没有操作,所得最多现金(也可以不设置这个状态)
    • dp[i][1]:第i天 第一次持有股票,所得最多现金
    • dp[i][2]:第i天 第一次不持有股票,所得最多现金
    • dp[i][3]:第i天 第二次持有股票,所得最多现金
    • dp[i][4]:第i天 第二次不持有股票,所得最多现金
  • Step2:确定递推公式
    • dp[i][0]:第i天 没有操作
      • 第i-1天 没有操作,第i天保持前一天的状态 → dp[i - 1][0]
    • dp[i][1]:第i天 第一次持有股票
      • 第i-1天没有操作,第i天第一次买入股票 →  dp[i-1][0]-prices[i]
      • 第i-1天第一次持有股票,第i天保持前一天的状态 →  dp[i-1][1]
    • dp[i][2]:第i天 第一次不持有股票
      • 第i-1天第一次持有股票,第i天第一次卖出股票 →  dp[i-1][1]+prices[i]
      • 第i-1天第一次不持有股票,第i天保持前一天的状态 →  dp[i-1][2]
    • dp[i][3]:第i天 第二次持有股票
      • 第i-1天第一次不持有股票,第i天第二次买入股票 →  dp[i-1][2]-prices[i]
      • 第i-1天第二次持有股票,第i天保持前一天的状态 →  dp[i-1][3]
    • dp[i][4]:第i天 第二次不持有股票
      • 第i-1天第二次持有股票,第i天第二次卖出股票 →  dp[i-1][3]+prices[i]
      • 第i-1天第二次不持有股票,第i天保持前一天的状态 →  dp[i-1][4]
  • Step3:初始化dp数组
    • 从递推公式可以看出,i是由i-1推导而来,因此需要初始化第一个元素
    • dp[0][0]:第0天 没有操作,所得最多现金为0
    • dp[0][1]:第0天 第一次持有股票(表明买入股票),所得最多现金为-prices[0]
    • dp[0][2]:第0天 第一次不持有股票(表明买入股票再卖出股票),所得最多现金为0(当天买入,当天卖出)
    • dp[0][3]:第0天 第二次持有股票(表明买入股票再卖出股票,第二次买入股票),所得最多现金为-prices[0]
    • dp[0][4]:第0天 第二次不持有股票(表明买入股票再卖出股票,第二次买入股票再卖出股票),所得最多现金为0
  • Step4:确定遍历顺序
    • 从递推公式可以看出,i是由i-1推导而来,因此需要从前向后遍历
  • Step5:打印dp数组(调试)
#include <iostream>
using namespace std;
#include <vector>

class Solution
{
public:
	int maxProfit(vector<int>& prices)
	{
		vector<vector<int>> dp(prices.size(), vector<int>(5, 0));
		dp[0][0] = 0;
		dp[0][1] = -prices[0];
		dp[0][2] = 0;
		dp[0][3] = -prices[0];
		dp[0][4] = 0;

		for (int i = 1; i < prices.size(); i++)
		{
			dp[i][0] = dp[i - 1][0];
			dp[i][1] = max(dp[i - 1][0] - prices[i], dp[i - 1][1]);
			dp[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2]);
			dp[i][3] = max(dp[i - 1][2] - prices[i], dp[i - 1][3]);
			dp[i][4] = max(dp[i - 1][3] + prices[i], dp[i - 1][4]);
		}
		return dp[prices.size() - 1][4];
	}
};

int main()
{
	vector<int> prices{ 3,3,5,0,0,3,1,4 };  // 6
	//vector<int> prices{ 1,2,3,4,5 };  // 4
	//vector<int> prices{ 7,6,4,3,1 };    // 0

	Solution s;
	int ans = s.maxProfit(prices);

	cout << ans << endl;

	system("pause");
	return 0;
}

示例:prices = [ 3,3,5,0,0,3,1,4 ]
       不操作  第一次持有  第一次不持有  第二次持有  第二次不持有
            0              1                   2                    3                    4
i=0       0             -3                   0                   -3                   0
i=1       0             -3                   0                   -3                   0
i=2       0             -3                   2                   -3                   2
i=3       0              0                   2                    2                   2
i=4       0              0                   2                    2                   2 
i=5       0              0                   3                    2                   5
i=6       0              0                   3                    2                   5
i=7       0              0                   4                    2                   6

4. 买卖股票的最佳时机4-最多买卖k次(LeetCode188) 

题目描述:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iv/description/

#include <iostream>
using namespace std;
#include <vector>

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

        for (int i = 1; i < prices.size(); i++)
        {
            for (int j = 1; j <= 2 * k; j += 2)
            {
                dp[i][j] = max(dp[i - 1][j - 1] - prices[i], dp[i - 1][j]);     // 第i天 第j次持有股票
                dp[i][j + 1] = max(dp[i - 1][j] + prices[i], dp[i - 1][j + 1]); // 第i天 第j次不持有股票
            }
        }

        return dp[prices.size() - 1][2 * k];
    }
};

int main()
{
    vector<int> prices{ 2,4,1 };  // 2
    int k = 2;

    //vector<int> prices{ 3,2,6,5,0,3 };  // 7
    //int k = 2;

    Solution s;
    int ans = s.maxProfit(k, prices);

    cout << ans << endl;

    system("pause");
    return 0;
}

5. 买卖股票的最佳时机含冷冻期-买卖多次,卖出有一天冷冻期(LeetCode309) 

题目描述:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-cooldown/description/

题目简述本题 = 买卖多次 + 冷冻期 →  相对于"买卖股票的最佳时机2(买卖多次)",本题加上了一个冷冻期

解题思路:动态规划五部曲

  • Step1:确定dp数组(一维)/dp表格(二维)、下标的含义
    • dp[i][0]:第i天不持有股票(非冷冻期),所得最多现金
    • dp[i][1]:第i天不持有股票(冷冻期),所得最多现金
    • dp[i][2]:第i天持有股票,所得最多现金
    • 持有股票 → 不持有股票(冷冻期) → 持有股票(非冷冻期)  每个状态只能有自身以及前一个状态推导得到(状态是环形的)
    • 在不含冷冻期的买卖股票问题中,冷冻期和非冷冻期的状态 统称为 不持有股票的状态
  • Step2:确定递推公式
    • dp[i][0]:第i天不持有股票(非冷冻期)
      • 第i-1天不持有股票(非冷冻期),第i天维持现状 → 所得现金就是昨天不持有股票(非冷冻期)的所得现金 dp[i - 1][0]
      • 第i-1天不持有股票(冷冻期),第i天从冷冻期转变为非冷冻期 → 所得现金就是昨天不持有股票(冷冻期)的所得现金 dp[i - 1][1]
    • dp[i][1]:第i天不持有股票(冷冻期)
      • 第i-1天持有股票,第i天卖出股票,转变为冷冻期 → 所得现金就是昨天持有股票的所得现金 加上 今天卖出股票所得现金 dp[i - 1][2]+prices[i]
      • 注1:第i天的冷冻期 不能由 第i-1天的冷冻期 推导得到,因为冷冻期只能持续一天
      • 注2:第i天的冷冻期 只能由 第i-1天持有股票 推导得到
    • dp[i][2]:第i天持有股票
      • 第i-1天不持有股票(非冷冻期),第i天买入股票 → 所得现金就是昨天不持有股票(非冷冻期)的所得现金 减去 今天买入股票的所花现金 dp[i - 1][0]-prices[i]
      • 第i-1天持有股票,第i天维持现状 → 所得现金就是昨天持有股票的所得现金 dp[i-1][2]
  • Step3:初始化dp数组
    • 从递推公式可以看出,i是由i-1推导而来,因此需要初始化第一个元素
    • dp[0][0]:第0天不持有股票(非冷冻期),所得最多现金为0
    • dp[0][1]:第0天不持有股票(冷冻期),所得最多现金为0
    • dp[0][2]:第0天持有股票(表明买入股票),所得最多现金为-prices[0]
  • Step4:确定遍历顺序
    • 从递推公式可以看出,i是由i-1推导而来,因此需要从前向后遍历 
  • Step5:打印dp数组(调试)
#include <iostream>
using namespace std;
#include <vector>

class Solution 
{
public:
    int maxProfit(vector<int>& prices) 
    {
        if (prices.size() == 1) return 0;

        vector<vector<int>> dp(prices.size(), vector<int>(3, 0));
        dp[0][0] = 0;
        dp[0][1] = 0;
        dp[0][2] = -prices[0];

        for (int i = 1; i < prices.size(); i++)
        {
            dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);              // 不持有股票(非冷冻期)
            dp[i][1] = dp[i - 1][2] + prices[i];                     // 不持有股票(冷冻期)
            dp[i][2] = max(dp[i - 1][0] - prices[i], dp[i - 1][2]);  // 持有股票
        }

        return max(dp[prices.size() - 1][0], dp[prices.size() - 1][1]);
    }
};

int main()
{
    vector<int> prices{ 1,2,3,0,2 };  // 3
    // vector<int> prices{ 1 };  // 0

    Solution s;
    int ans = s.maxProfit(prices);

    cout << ans << endl;

    system("pause");
    return 0;
}

6. 买卖股票的最佳时机含手续费-买卖多次,每次有手续费(LeetCode714) 

题目描述:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/description/

题目简述本题 = 买卖多次 + 手续费 →  相对于"买卖股票的最佳时机2(买卖多次)",本题加上了一个手续费

解题思路:动态规划五部曲

  • Step1:确定dp数组(一维)/dp表格(二维)、下标的含义
    • dp[i][0]:第i天不持有股票,所得最多现金
    • dp[i][1]:第i天持有股票,所得最多现金
  • Step2:确定递推公式
    • dp[i][0]:第i天不持有股票 可以由两个状态推导出来
      • 第i-1天不持有股票,第i天保持现状 → 所得现金就是昨天不持有股票的所得现金 dp[i - 1][0]
      • 第i-1天持有股票,第i天卖出股票 → 所得现金就是按照今天股票价格卖出后所得现金 dp[i - 1][1] + prices[i] - fee
        • 注:需要在计算卖出操作的时候减去手续费(本题和"买卖股票的最佳时机2"的唯一区别)
    • dp[i][1]:第i天持有股票 可以由两个状态推导出来
      • 第i-1天不持有股票,第i天买入股票 → 所得现金就是买入今天的股票后所得现金 dp[i-1][0]-prices[i]
      • 第i-1天持有股票,第i天保持现状 → 所得现金就是昨天持有股票的所得现金 dp[i-1][1]
  • Step3:初始化dp数组
    • 从递推公式可以看出,i是由i-1推导而来,因此需要初始化第一个元素
    • dp[0][0]:第0天不持有股票,所得最多现金为0
    • dp[0][1]:第0天持有股票(表明买入股票),所得最多现金为-prices[0]
  • Step4:确定遍历顺序
    • 从递推公式可以看出,i是由i-1推导而来,因此需要从前向后遍历 
  • Step5:打印dp数组(调试)
#include <iostream>
using namespace std;
#include <vector>

class Solution 
{
public:
    int maxProfit(vector<int>& prices, int fee) 
    {
        vector<vector<int>> dp(prices.size(), vector<int>(2, 0));
        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] - fee);  // 唯一区别
            dp[i][1] = max(dp[i - 1][0] - prices[i], dp[i - 1][1]);
        }
        return dp[prices.size() - 1][0];
    }
};

int main()
{
    //vector<int> prices{ 1,3,2,8,4,9 };  // 8
    //int fee = 2;

    vector<int> prices{ 1,3,7,5,10,3 };  // 6
    int fee = 3;

    Solution s;
    int ans = s.maxProfit(prices, fee);

    cout << ans << endl;

    system("pause");
    return 0;
}

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

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

相关文章

【架构设计】软件设计原则中的7种耦合和内聚(详解)

文章目录 一、前言二、内聚1、定义2、7 种内聚类型及其描述3、设计要求 三、耦合1、定义2、7 种耦合类型及其描述3、设计要求 四、总结 一、前言 耦合&#xff08;Coupling&#xff09;和内聚&#xff08;Cohesion&#xff09;是衡量软件模块设计质量的两个非常重要的概念。高…

2024实验班选拔考试(热身赛)

比赛传送门 邀请码&#xff1a;2024wksyb A. 简单的数列问题 签到&#xff0c;记得开long long。 #include<bits/stdc.h> #define rep(i,a,b) for (int ia;i<b;i) #define per(i,a,b) for (int ia;i>b;--i) #define se second #define fi first #define endl …

linux进程篇总结——实战——自定义shell

前言&#xff1a;经过过去两章十二篇文章的学习&#xff0c;我们已经知道了进程的基本概念以及进程的控制方法。 本篇内容就是使用过去学习的内容自己写一个功能简单的shell外壳程序&#xff0c; 也就是我们使用的bash命令行。 本篇内容是过去进程知识的集大成者。 我们在这个实…

智慧能源管理:助力公共机构节能增效

一、背景&#xff1a; 在全球倡导绿色发展、节能减排的时代浪潮下&#xff0c;公共机构作为社会服务的重要提供者&#xff0c;能源消耗量大&#xff0c;特别是在照明方面能源消耗问题尤为突出。从政府办公楼的日常照明&#xff0c;到学校教室的学习照明&#xff0c;再到医院走…

计算机组成原理 - 存储系统

存储系统 考纲内容 存储器的分类层次化存储器的基本结构半导体随机存储器(RAM) SRAM、DRAM、Flash存储器主存储器 DRAM芯片和内存条、多模块存储器、主存储器和CPU之间的连接外部存储器 磁盘存储器、固态硬盘(SSD)高速缓冲存储器(Cache) Cache的基本原理&#xff1a;Cache和主…

解读智慧车间生产线的智慧大脑:ARMxy 工业计算机边缘控制器

在现代工业制造中&#xff0c;智慧车间生产线的建设已成为提高生产效率、降低成本、提升产品质量的关键。而 ARMxy 工业计算机边缘控制器作为智慧车间生产线的智慧大脑&#xff0c;正发挥着越来越重要的作用。 ARMxy 工业计算机边缘控制器是一种基于 ARM 架构的嵌入式工业计算机…

JavaWeb基础1:HTML/CSS/JS/HTTP

JavaWeb基础1&#xff1a;HTML/CSS/JS/HTTP (qq.com)

C-sharp-console-gui-framework:C#控制台应用程序的GUI框架

推荐一个.Net开源项目&#xff0c;方便我们基于控制台创建图形用户界面&#xff08;GUI&#xff09;应用程序。 01 项目简介 ConsoleGUI是一个简单的布局驱动.NET框架&#xff0c;用于创建基于控制台的GUI应用程序。 核心功能&#xff1a; **布局驱动&#xff1a;**与WPF或H…

WCN7851 WIFI7适配RK3588实战

一、平台信息 平台:触觉智能IDO-EVB3588-V1 WIFI模组:欧飞信O7851PM Kernel版本:GNU/Linux 5.10.110 aarch64 系统版本:Ubuntu 20.04.6 LTS 搭载RK3588高性能SOC,集成了四核Cortex-A76和四核Cortex-A55 CPU,主频高达2.4G O7851PM与开发板连接实物图如下,模块通过M.2转…

ctfhub文件上传

⽆验证 上传⼀句话⽊⻢&#xff0c;发现上传成功 1.php ⼀句话⽊⻢内容&#xff1a; <?php eval($_POST[cmd]);?> 上传⼀句话⽊⻢&#xff0c;发现上传成功 http://challenge-8b27d18368ecc25c.sandbox.ctfhub.com:10800/upload/1.ph p 前端验证 开启题⽬ 上传⼀个…

学习日志8.5--ARP攻击与防范

目录 ARP欺骗攻击 ARP泛洪防范&#xff08;动态ARP检测&#xff09; ARP欺骗攻击 ARP中间人攻击&#xff0c;中间人可以通过交换机查询交换表获取主机和网关的IP地址信息中间者通过ARP的查询可以知道PC2的IP地址和MAC地址&#xff0c;知道R2的IP地址和MAC地址&#xff0c;攻…

CVE-2023-1313

开启靶场 url访问/install来运行安装 http://eci-2ze0wqx38em0qticuhug.cloudeci1.ichunqiu.com/install/ 得知其用户和密码为admin 登录 查找文件上传位置 上传一句话木马文件 <?php echo phpinfo();eval($_POST[flw]);?> 下载查看上传木马路径 复制路径 /storag…

59 函数参数——默认值参数

在定义函数时&#xff0c;Python 支持默认值参数&#xff0c;在定义函数时可以为形参设置默认值。 在调用带有默认值参数的函数时&#xff0c;可以不用为设置了默认值的形参进行传递&#xff0c;此时函数将会直接使用函数定义时设置的默认值&#xff0c;当然也可以通过显式赋值…

第四届机械制造与智能控制国际学术会议(ICMMIC 2024,9月27-29)

2024年第四届机械制造与智能控制国际学术会议&#xff08;ICMMIC 2024&#xff09;将于2024年9月27-29日在中国沈阳沈阳理工大学举行。 本会议将围绕“机械制造、智能控制”的最新研究领域&#xff0c;促进机械工程、兵器科学与技术、控制科学与工程等相关学科的发展与交叉融合…

AUTOSAR之ECUM

1、EcuM简介 EcuM&#xff08;ECU State Management&#xff09;ECU状态管理模块属于AUTOSAR系统服务中模式管理部分&#xff0c;主要功能是管理ECU的上下电&#xff0c;初始化和反初始化OS&#xff0c;SchM&#xff0c;BswM以及其他一些驱动模块。 AUTOSAR 4.4版本前Ec…

WPF学习(5)- Border控件(边框布局)+GridSplitter分割窗口

严格来说&#xff0c;Border并不是一个布局控件&#xff0c;因为它并不是Panel的子类&#xff0c;而是Decorator装饰器的子类&#xff0c;而Decorator继承于FrameworkElement。我们要先看看它的父类Decorator。 public class Decorator : FrameworkElement, IAddChild {public…

【区块链+医疗健康】医保监管飞检魔方可信链 | FISCO BCOS应用案例

《“十四五”全民医疗保障规划》提出加快健全基金监管体制机制&#xff0c;要求飞行检查全覆盖。近年来&#xff0c;国家医保局 飞行检查专项行动&#xff0c;累计发现问题 70 多万家次&#xff0c;累计追回医保基金 340 多亿元。而飞行检查面临检查时间短、 工作任务重、数据多…

Linux 使用kickstart创建脚本实现新建虚拟机自动安装

Linux版本&#xff1a;红帽7.9 确保网络配置可用&#xff0c;本地仓库可用&#xff0c;同时已经挂载/dev/cdrom,可用yum list查看 一、环境配置&#xff1a; 1、首先保证是有图形界面 利用hostnamectl 查看 如果没有安装图形界面可以使用yum group install "Server wi…

源码编译安装LAMP(HTTP服务,MYSQL ,PHP)

一、安装Apache 可在生产环境使 下载在 下面两个插件是httpd2.4以后的版本所需要 tar xf apr-1.6.2.tar.gz tar xf apr-util-1.6.0.tar.gz 虽然xf通常足够&#xff0c;但使用与压缩算法对应的选项可以提供更好的控制。 tar xjf httpd-2.4.29.tar.bz2 mv apr-1.6.2 httpd-2.4.…

How to run OpenAI Gym .render() over a server

题意&#xff1a;怎样在服务器上运行 OpenAI Gym 的 .render() 方法 问题背景&#xff1a; I am running a python 2.7 script on a p2.xlarge AWS server through Jupyter (Ubuntu 14.04). I would like to be able to render my simulations. 通过 Jupyter&#xff08;在 U…