算法 - 动态规划

动态规划是一种自底向上的算法,通常用于解决最大、最小等最值问题

能使用动态规划解决的问题,一定具备:

  • 重叠子问题:和暴力搜索不同,需要记录子问题的解,避免重复求解(剪枝)
  • 最优子结构:子问题达到最值,整体才能达到最值,即以小见大
  • 状态转移方程:在每个“状态”做出的“选择”会到达什么“状态”

然后就以合适的顺序填表,穷举所有情况并求最值即可
整体流程:明确 base case -> 明确「状态」-> 明确「选择」 -> 定义 dp 数组/函数的含义

文章目录

  • 1.凑零钱
  • 2.最长递增子序列*
    • 3.最长回文子序列*
    • 最长回文子串
    • 最长公共子序列
    • 最长公共子串
  • 4.打家劫舍
  • 5.打家劫舍II
  • 6.打家劫舍III *
  • 7.含冷冻期的股票买卖
    • 股票买卖的最佳时机II *
    • 股票买卖的最佳时机III
  • 8.编辑距离
    • 带权编辑距离
  • 8.01背包问题
  • 9.分割等和子集(背包问题模板)
  • 10.凑硬币II(完全背包问题)
  • 11.目标和(01背包)
  • 12 n个骰子的点数

1.凑零钱

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。

class Solution(object):def coinChange(self, coins, amount):""":type coins: List[int]:type amount: int:rtype: int"""# F[n]为凑n所需要的最少硬币数# F[n] = min(F[n-k]) + 1,其中k是每个面值dp = [10001 for _ in range(amount + 1)]dp[0] = 0for c in coins:if c <= amount:dp[c] = 1# 填表for i in range(1, amount + 1):for c in coins:if i - c >= 0:dp[i] = min(dp[i], dp[i - c] + 1)return dp[-1] if dp[-1] != 10001 else -1

2.最长递增子序列*

  • 明确状态:dp[n] = 以下标n结束的(而非从下标0到下标n的,这种弱绑定),最长序列长度
  • 不是所有的题目都采用“强绑定”,只能说随机应变
class Solution(object):def lengthOfLIS(self, nums):""":type nums: List[int]:rtype: int"""# F[n] = max(F[k] + 1) if nums[k] < nums[n]n = len(nums)dp = [1 for _ in range(n)]res = 1for i in range(n):for j in range(i):dp[i] = max(dp[j] + 1, dp[i]) if nums[i] > nums[j] else dp[i]res = max(res, dp[i])return res

3.最长回文子序列*

  • dp[ i ][ j ] = 从下标 i 到下标 j 的最长回文子序列的长度(不包括头尾,即 s[ i ] != s[ j ] 时 dp[ i ][ j ] 可以不为 0)
  • 每次填一个左斜的列
class Solution(object):def longestPalindromeSubseq(self, s):""":type s: str:rtype: int"""# dp[i][j] = 下标i到j中,最长回文子序列的长度length = len(s)dp = [[1 for _ in range(length)] for _ in range(length)]# 初始化两对角线for i in range(length - 1):if s[i] == s[i + 1]:dp[i][i + 1] = 2# 填表for k in range(2, length):i, j = 0, kwhile (i < length and j < length):if (s[i] == s[j]):dp[i][j] = dp[i + 1][j - 1] + 2else:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])i += 1j += 1return dp[0][length - 1]

最长回文子串

  • 填表的时候,每个位置需要查看其左下方向的值,所以填表顺序可以是,先将对角线上的两列初始化,再按列填表
  • dp[ i ][ j ] = s[ i : j + 1] 是否是回文子串
class Solution(object):def longestPalindrome(self, s):""":type s: str:rtype: str"""if s == "":return s# 动态规划length = len(s)table = [[False for i in range(length)] for j in range(length)]  # n*n的矩阵:指示从i到j是否回文start, end = 0, 0# 初始化对角线上的两列for i in range(length):table[i][i] = Truefor i in range(length-1):if s[i] == s[i+1]:table[i][i+1] = Truestart, end = i, i + 1# 填表:按列的顺序for j in range(2, length):for i in range(0, j-1):flag = table[i+1][j-1]if flag and s[i] == s[j]:table[i][j] = Trueif j - i > end - start:start, end = i, jreturn s[start:end+1]

最长公共子序列

class Solution(object):def longestCommonSubsequence(self, text1, text2):""":type text1: str:type text2: str:rtype: int"""# dp[i][j] = t1的前i个字母,和t2的前j个字母的最长相同子序列长度l1, l2 = len(text1), len(text2)dp = [[0 for _ in range(l2 + 1)] for _ in range(l1 + 1)]# 填表,按行填for i in range(1, l1 + 1):for j in range(1, l2 + 1):if text1[i - 1] == text2[j - 1]:dp[i][j] = dp[i - 1][j - 1] + 1else:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])return dp[-1][-1]

最长公共子串

class Solution:def LCS(self , str1 , str2 ):# write code herem, n = len(str1), len(str2)if m == 1:return str1 elif n == 1:return str2 dp = [[0 for _ in range(n)] for _ in range(m)]res, end1idx = 0, 0 # 初始化for i in range(m):if str1[i] == str2[0]:dp[i][0] = 1res = 1end1idx = ifor j in range(n):if str2[j] == str1[0]:dp[0][j] = 1# 填表for i in range(1, m):for j in range(1, n):if str1[i] == str2[j]:dp[i][j] = dp[i - 1][j - 1] + 1end1idx = i if res < dp[i][j] else end1idxres = max(res, dp[i][j])return str1[end1idx - res + 1: end1idx + 1]

4.打家劫舍

一般的动态规划(推荐)

class Solution(object):def rob(self, nums):""":type nums: List[int]:rtype: int"""# 写个动态规划# 状态:偷到i号房子时的最大值# 选择:是否偷当前的房子# dp[i]=max(dp[i - 2] + nums[i], dp[i - 1])length = len(nums)if length == 1:return nums[0]dp = [0 for _ in range(length)]dp[0] = nums[0]dp[1] = nums[0] if nums[0] > nums[1] else nums[1]for i in range(2, length):steal = dp[i - 2] + nums[i]not_steal = dp[i - 1]dp[i] =  steal if steal > not_steal else not_stealreturn dp[length - 1]

还可以使用自顶向下递归+备忘录。这种方法引入了递归,比较适合解决树结构的问题——打家劫舍III

class Solution(object):def rob(self, nums):""":type nums: List[int]:rtype: int"""memo = [-1 for _ in range(len(nums))]return self.search(0, nums, memo)  # 或memo[0]def search(self, idx, nums, memo):length = len(nums)# 递归出口if idx > length - 1:return 0# 查表避免计算elif memo[idx] != -1:return memo[idx]# 后根,先递归后返回,以获取当前序列之后的信息else:steal = nums[idx] + self.search(idx + 2, nums, memo)not_steal = self.search(idx + 1, nums, memo)memo[idx] = max(steal, not_steal)return memo[idx]

5.打家劫舍II

将输入变成环形,和 I 相比讨论两种情况,取最大值。

class Solution(object):def rob(self, nums):""":type nums: List[int]:rtype: int"""length = len(nums)if length == 1:return nums[0]elif length <= 3:return max(nums)# 分两种情况:[1:]和[:-1]nums1 = nums[1: ]nums2 = nums[: -1]dp1 = [0 for _ in range(length - 1)]dp1[0] = nums1[0]dp1[1] = max(nums1[0], nums1[1])for i in range(2, length - 1):dp1[i] = max(dp1[i - 1], dp1[i - 2] + nums1[i])dp2 = [0 for _ in range(length - 1)]dp2[0] = nums2[0]dp2[1] = max(nums2[0], nums2[1])for i in range(2, length - 1):dp2[i] = max(dp2[i - 1], dp2[i - 2] + nums2[i])return max(dp1[-1], dp2[-1])

6.打家劫舍III *

  • 一道典中典的题:动态规划+树结构 = memo+递归
  • 第二次做的时候思维卡在了,想先获取某节点的父节点,和父节点的父节点(类似于普通dp的想法)来确定当前点的值,使用递归的好处是可以“知道”后续的信息,在当前加以判断

对于树结构的问题,明确每个节点该干什么

class Solution(object):def rob(self, root):""":type root: TreeNode:rtype: int"""# dp+树=memo+递归memo = dict()def search(node):# 出口if node is None:return 0# 查表if memo.has_key(node):return memo[node]# 抢l, r = 0, 0if node.left is not None:l = search(node.left.left) + search(node.left.right)if node.right is not None:r = search(node.right.left) + search(node.right.right)yes = node.val + l + r# 不抢no = search(node.left) + search(node.right)# 取最大值写入memomemo[node] = max(yes, no)return memo[node]return search(root)

7.含冷冻期的股票买卖

给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。​
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

  • 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
  • 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
class Solution(object):def maxProfit(self, prices):""":type prices: List[int]:rtype: int"""# 状态:已买/未买/冷冻期  (状态不要写成:买入/卖出/冷冻,分清楚状态和动作)# 选择:买入/卖出/不变# DFAn = len(prices)have = [0 for _ in range(n)]not_have = [0 for _ in range(n)]freeze = [0 for _ in range(n)]have[0] = -prices[0]for i in range(1, n):# 第i天*持有*股票的最大利润:昨天持有,今天持有/昨天没有,今天买入have[i] = max(have[i - 1], not_have[i - 1] - prices[i])# 第i天*不持有*股票的最大利润:昨天不持有,今天也不持有/昨天卖出,今天冷冻not_have[i] = max(not_have[i - 1], freeze[i - 1])# 第i天***进入冷冻(卖出)***的最大利润freeze[i] = have[i - 1] + prices[i]# 最后一天处于不持有/刚卖出时的利润最大return max(not_have[-1], freeze[-1])

股票买卖的最佳时机II *

  • 可以多次交易,但每次只能持有一个股票
  • 状态DP,加入当前是否已持有股票的状态
class Solution(object):def maxProfit(self, prices):""":type prices: List[int]:rtype: int"""# 状态DP# dp[n][0] 代表截至第n天,不持有股票的最大利润,dp[n][1]代表持有股票的最大利润length = len(prices)dp = [[0, 0] for _ in range(length)]dp[0][1] = -prices[0]for i in range(1, length):dp[i][0] = max(dp[i - 1][0], prices[i] + dp[i - 1][1])  # 昨天没买今天不买/昨天买了今天卖dp[i][1] = max(dp[i - 1][0] - prices[i], dp[i - 1][1])  # 昨天没买今天买/昨天买了今天不卖return dp[-1][0]

股票买卖的最佳时机III

  • 和上面类似,但限制最多只能交易两次
  • 需要额外加入两个状态
class Solution(object):def maxProfit(self, prices):""":type prices: List[int]:rtype: int"""# 状态dp plus# dp[n]:第一位代表截至第n天,第二位代表是否持有股票,第三位代表完成的购买次数length = len(prices)dp = [[[0, 0, 0] for _ in range(2)] for _ in range(length)]# 初始化dp[0][1][1] = -prices[0]# 将不合理位置设置为负值!!!dp[0][1][0] = -1000000dp[0][1][2] = -1000000dp[0][0][1] = -1000000dp[0][0][2] = -1000000# 填表for i in range(1, length):dp[i][1][1] = max(dp[i - 1][1][1], dp[i - 1][0][0] - prices[i])  # 第i天有股票买过一次:可能是之前买的,也可能是今天买,取利润最大dp[i][1][2] = max(dp[i - 1][1][2], dp[i - 1][0][1] - prices[i]) # 第i天有股票买过两次:可能是之前买的,也可能是今天买,取利润最大dp[i][0][1] = max(dp[i - 1][0][1], dp[i - 1][1][1] + prices[i])  # 第i天没股票买过一次:可能是之前卖的,也可能是今天卖的dp[i][0][2] = max(dp[i - 1][0][2], dp[i - 1][1][2] + prices[i])  # 第i天没股票买过两次:可能是之前卖的,也可能是今天卖的return max(dp[-1][0])

8.编辑距离

问题复杂,题解简介。关键是找到DP数组的定义。
选择思路——引用leetcode下面的高赞评论:

  • 问题1:如果 word1[0…i-1] 到 word2[0…j-1] 的变换需要消耗 k 步,那 word1[0…i] 到 word2[0…j] 的变换需要几步呢?

  • 答:先使用 k 步,把 word1[0…i-1] 变换到 word2[0…j-1],消耗 k 步。再把 word1[i] 改成 word2[j],就行了。如果 word1[i] == word2[j],什么也不用做,一共消耗 k 步,否则需要修改,一共消耗 k + 1 步。

  • 问题2:如果 word1[0…i-1] 到 word2[0…j] 的变换需要消耗 k 步,那 word1[0…i] 到 word2[0…j] 的变换需要消耗几步呢?

  • 答:先经过 k 步,把 word1[0…i-1] 变换到 word2[0…j],消耗掉 k 步,再把 word1[i] 删除,这样,word1[0…i] 就完全变成了 word2[0…j] 了。一共 k + 1 步。

  • 问题3:如果 word1[0…i] 到 word2[0…j-1] 的变换需要消耗 k 步,那 word1[0…i] 到 word2[0…j] 的变换需要消耗几步呢?

  • 答:先经过 k 步,把 word1[0…i] 变换成 word2[0…j-1],消耗掉 k 步,接下来,再插入一个字符 word2[j], word1[0…i] 就完全变成了 word2[0…j] 了。

class Solution(object):def minDistance(self, word1, word2):""":type word1: str:type word2: str:rtype: int"""m, n = len(word1), len(word2)dp = [[1000 for _ in range(n + 1)] for _ in range(m + 1)]  # dp[i][j]:word1前i个(坐标i - 1)和word2前j个匹配的最小操作数# 初始化for i in range(m + 1):dp[i][0] = i for j in range(n + 1):dp[0][j] = j# 填表for i in range(1, m + 1):for j in range(1, n + 1):# 无需进行任何操作if word1[i - 1] == word2[j - 1]:dp[i][j] = dp[i - 1][j - 1]else:dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1])return dp[m][n]

带权编辑距离

给定两个字符串str1和str2,再给定三个整数ic,dc和rc,分别代表插入、删除和替换一个字符的代价,请输出将str1编辑成str2的最小代价

class Solution:def minEditCost(self , str1 , str2 , ic , dc , rc ):# write code here# dp[i][j] 代表从s1[0...i] 修改为s2[0...j]的代价# dp[i][j] = dp[i-1][j-1] if equals else ...m, n = len(str1), len(str2)dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)]for i in range(m + 1):dp[i][0] = i * dc for j in range(n + 1):dp[0][j] = j * ic for i in range(1, m + 1):for j in range(1, n + 1):if str1[i - 1] == str2[j - 1]:dp[i][j] = dp[i - 1][j - 1] else:dp[i][j] = min(dp[i - 1][j] + dc, dp[i][j - 1] + ic, dp[i - 1][j - 1] + rc)return dp[-1][-1]

8.01背包问题

  • 算法设计课上的例题。物品只能选择装入/不装入,所以是01背包。
  • 01背包的问题形式:凑够目标和target ——(能否)凑够target,凑target有几种方式
# dp[i][j] 代表对于物品i,背包容量为j时能承载的最大价值
for i in range(num_items):for j in range(capacity):dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + val[i])  # 选择装物品i或者不装物品i(伪码,未做防止越界的处理
return dp[-1][-1]

9.分割等和子集(背包问题模板)

抽象成可装载重量为 sum / 2 的背包,每个物品的重量为 nums[i],在 sum/2 的前提下,尽量往里装最多的数字,如果恰好能为sum / 2则满足题意

class Solution(object):def canPartition(self, nums):""":type nums: List[int]:rtype: bool"""# 特判奇偶,奇数不能划分summary = sum(nums)if summary % 2 == 1:return Falsetarget = summary // 2n = len(nums)dp = [[0 for _ in range(target + 1)] for _ in range(n)]# 初始化首行if nums[0] == target:return Truefor i in range(target + 1):dp[0][i] = nums[0] if i >= nums[0] else 0# 填表:经典的背包模板for i in range(1, n):for j in range(target + 1):# 不能装下物品iif j < nums[i]:dp[i][j] = dp[i - 1][j]# 可以装下物品ielse:dp[i][j] = max(dp[i - 1][j], (dp[i - 1][j - nums[i]] if nums[i] <= j else 0) + nums[i])return dp[-1][-1] == target

可以进一步优化空间:因为每行在填写时只使用上一行dp,所以dp只保留一行即可

10.凑硬币II(完全背包问题)

  • 处理背包问题一定要注意dp数组的定义,不要少定义下标
  • 完全背包问题的每种物品数量无限
  • 这道题同样可以对dp数组进行空间优化
class Solution(object):def change(self, amount, coins):""":type amount: int:type coins: List[int]:rtype: int"""# 凑和,背包问题;每种物品无限,完全背包问题# dp[i][j]:前i个硬币凑和jlength = len(coins)dp = [[0 for _ in range(amount + 1)] for _ in range(length)]# 初始化:凑0元有1种方式for i in range(length):dp[i][0] = 1# 初始化:只用首个硬币for j in range(1, amount + 1):if j % coins[0] == 0:dp[0][j] = 1# 填表for i in range(1, length):for j in range(amount + 1):dp[i][j] = dp[i - 1][j]  # 不用第i个硬币dp[i][j] += dp[i][j - coins[i]] if (j - coins[i] >= 0) else 0  # 用第i个硬币return dp[-1][-1]

11.目标和(01背包)

给你一个整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 ‘+’ 或 ‘-’ ,然后串联起所有整数,可以构造一个
表达式 : 例如,nums = [2, 1] ,可以在 2 之前添加 ‘+’ ,在 1 之前添加 ‘-’ ,然后串联起来得到表达式
“+2-1” 。 返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

class Solution(object):def findTargetSumWays(self, nums, target):""":type nums: List[int]:type target: int:rtype: int"""# dp[i][j]:前i个数字加减 得到总和j 的方法数目# dp[i][j] = dp[i - 1][j - nums[i]] + dp[i - 1][j + nums[i]]"""!!!!数组的列范围 要开到[-sum(nums), sum(nums)]而非[-target, target]!!!!"""# 特判summary = sum(nums)if summary < target:return 0n = len(nums)dp = [[0 for _ in range(2 * summary + 1)] for _ in range(n)]  # 包含负数,下标target处为0# 初始化首行for j in range(2 * summary + 1):if nums[0] == 0:dp[0][summary] = 2breakelse:real_val = j - summaryif nums[0] == real_val or -nums[0] == real_val:dp[0][j] = 1# 填表for i in range(1, n):for j in range(2 * summary + 1):minus = j - nums[i]plus = j + nums[i]dp[i][j] += dp[i - 1][minus] if minus >= 0 else dp[i - 1][0]dp[i][j] += dp[i - 1][plus] if plus <= 2 * summary else dp[i - 1][0]return dp[-1][summary + target]

12 n个骰子的点数

  • 把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率
class Solution(object):def dicesProbability(self, n):""":type n: int:rtype: List[float]"""# dp[i][j] = 前i个骰子点数和为j的概率# dp[i][j] = sigma(dp[i - 1][j - k]), k = 1...6dp = [[0 for _ in range(6 * n + 1)] for _ in range(n)]# 初始化for i in range(1, 7):dp[0][i] = 0.16667# 填表for i in range(1, n):for j in range(i + 1, 6 * i + 7):for k in range(1, 7):dp[i][j] += dp[i - 1][j - k] / 6 if j - k > 0 else 0return dp[-1][n:]

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

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

相关文章

5G在工业互联网应用的机遇与挑战

移动通讯经过十年一代的发展&#xff0c;已经从1G发展到了5G&#xff0c;峰值速率实现十年千倍的增长&#xff0c;1G到4G是面向个人的&#xff0c;而5G是面向产业互联网和智慧城市服务。5G是一个颠覆性的技术&#xff0c;低时延&#xff08;每秒钟下载一部高清电影&#xff09;…

算法 - 前缀和

记录在做hot100时遇到的前缀和的题目。 目前见过的题目&#xff0c;都是前缀和结合其它的方法一起使用&#xff1a;用于求取一段连续路径的和&#xff08;最大值/最小值/目标出现次数&#xff09;。 需要注意的是&#xff0c;前缀和的判定方法是node2.val-node1.val target&am…

[C#.NET 拾遗补漏]10:理解 volatile 关键字

要理解 C# 中的 volatile 关键字&#xff0c;就要先知道编译器背后的一个基本优化原理。比如对于下面这段代码&#xff1a;public class Example {public int x;public void DoWork(){x 5;var y x 10;Debug.WriteLine("x " x ", y " y);} }在 Releas…

跟我一起学.NetCore之MediatR好像有点火

前言随着微服务的流行&#xff0c;而DDD(领域驱动设计)也光速般兴起&#xff0c;CRQS(Command Query Responsibility Seperation--命令查询职责分离)、领域事件名词是不是经常在耳边环绕&#xff0c;而MediatR组件经常用来对其技术的落地&#xff0c;凭这&#xff0c;小伙伴们说…

数据结构 - 单调栈、单调队列

单调栈&#xff1a;每日温度 请根据每日 气温 列表 temperatures &#xff0c;请计算在每一天需要等几天才会有更高的温度。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替单调栈基本只处理NGE问题&#xff08;Next GreaterElement&#xff09;。对序列中每个元…

不想写脚本清理 mongodb 中的垃圾数据,ttlIndex 能帮到你!

mongodb一直都在不断的更新&#xff0c;不断的发展&#xff0c;那些非常好玩也非常实用的功能都逐步加入到了mongodb中&#xff0c;这不就有了本篇对ttlindex的介绍&#xff0c;刚好我们的生产业务场景中就有一个案例。。。一&#xff1a;案例分析 生产的推荐系统要给用户发送短…

数据结构 - 最小堆最大堆

可以在O(nlogn)的时间复杂度内完成排序典型的用法是&#xff0c;寻找 第k个/前k个 最大/最小元素&#xff0c;k个有序序列合并 1.合并K个升序链表&#xff08;最小堆实现&#xff09; 或许可以改进成每次堆只存放K个元素&#xff1f; # Definition for singly-linked list. …

python程序启动其他python程序,如何使用Python启动应用程序的实例?

I am creating a Python script where it does a bunch of tasks and one of those tasks is to launch and open an instance of Excel. What is the ideal way of accomplishing that in my script?解决方案While the Popen answers are reasonable for the general case, I…

工作这几年所获、所感、所悟

【导读】截止到目前&#xff0c;给甲方所做项目已接近尾声&#xff0c;在此写下一点个人关于技术方面的感受。若后续时间上允许或充裕的话&#xff0c;打算私下花一点时间分享封装可通用的组件今年也是我首次带小伙伴&#xff0c;有刚毕业没什么技术经验&#xff0c;也有毕业不…

后端学习 - 基础 《Java编程的逻辑》读书笔记

文章目录一 基础概念1 有关Java2 JVM / JDK / JRE3 与C的联系和区别4 各类型数据占用空间大小5 和 equals() 的区别、hashCode() 方法6 包装类型7 final 关键字8 参数传递机制&#xff1a;值传递9 String 的内存情况10 访问修饰符11 引用拷贝、浅拷贝与深拷贝三 面向对象1 面向…

cheatengine找不到数值_彩票中奖500万,领了还不到一半?这些问题不解决,钱都拿不走...

长期以来&#xff0c;“一夜暴富”是很多人梦寐以求的梦想&#xff0c;而作为最能让人“一夜暴富”的方式要数我国的福利彩票了&#xff0c;这也是很多人最容易活动暴富的机会&#xff0c;不少彩民长久以来一直买彩票的梦想就是“一夜暴富”。而突然暴富是很多人的梦想&#xf…

一站式Web开发套件BeetleX.WebFamily

BeetleX.WebFamily是一款前后端分离的Web开发套件&#xff0c;但它并不依赖于nodejs/npm/webpack等相关工具&#xff1b;而使用自身实现的方式来完成前后端分离的Web应用开发&#xff1b;套件以组件的方式发布&#xff0c;只需要在项目引用相关组件即可实现前后端分离开发&…

.NET架构小技巧(2)——访问修饰符正确姿势

在C#中&#xff0c;访问修饰符是使用频率很高的一组关键字&#xff0c;一共四个单词六个组合&#xff1a;public,internal,protected internal,protected,private protected,private&#xff0c;如果你对这些关键字非常清楚&#xff0c;请跳过&#xff0c;节省时间&#xff1b;…

能源36号文解读_IDC报告预测:今年中国新能源汽车销量将达116万辆,未来五年复合增长率36%_详细解读_最新资讯_热点事件...

编者按&#xff1a;本文来自36氪「 未来汽车日报」&#xff0c;(微信公众号ID&#xff1a;auto-time)&#xff0c;作者&#xff1a;秦章勇。 来源&#xff1a;IDC作者 | 秦章勇编辑 | 周游12月3日&#xff0c;在2020世界智能汽车大会上&#xff0c;IDG亚洲(国际数据(亚洲)集团)…

后端学习 - 容器

文章目录一 简介二 底层数据结构总结1 List2 Set3 Queue4 Map三 Collection 的子接口 List1 ArrayList 与 Vector2 ArrayList 与 LinkedList3 ArrayList 的 JDK 7/8 差异4 ArrayList 的构造方法与扩容机制*四 Collection 的子接口 Set1 HashSet、LinkedHashSet 和 TreeSet2 Has…

简单聊聊AspNetCore的启动流程

首先&#xff0c;得和大家达成一个共识&#xff0c;即AspNetCore项目其实就是一个控制台项目。可以简单的理解&#xff0c;AspNetCore就是将一个Web服务器宿主在一个进程(即控制台)中&#xff0c;然后它在这个进程中进行http请求的监听处理。AspNetCore中默认使用kestrel作为we…

共聚焦图片怎么加标尺_聚焦扶贫政策,打造小康生活

导语&#xff1a;农村独栋小楼、整洁的水泥路……扶贫产业蓬勃发展&#xff0c;我省结合实际&#xff0c;狠抓特色产业&#xff0c;助力脱贫攻坚&#xff0c;实现乡村振兴。武宁县&#xff1a;“四个聚焦”巩固脱贫成果2020年是全面建成小康社会目标实现之年&#xff0c;是全面…

后端学习 - 并发编程

文章目录零 基本概念1 CAS、ABA 问题和原子变量2 this 引用逸出3 不变性 immutable4 同步、异步、阻塞、非阻塞5 JMM6 同步方案演示&#xff1a;计数器 demo*一 进程与线程1 区别与联系2 Java内存区域3 线程组4 线程的上下文切换5 并发与并行6 线程的生命周期与状态二 线程间的…

打造跨平台.NET Core后台服务

续之前讲的在TopShelf上部署ASP.NET Core程序&#xff0c;作为后台服务运行&#xff0c;自从.NET Core 3.0出现以后&#xff0c;出现了自带的Generic Host&#xff0c;使得自托管服务变为可能。这种方式和TopShelf方式一样&#xff0c;可以直接F5进行服务的调试&#xff0c;也为…

iphone桌面横屏设置在哪里_我和我各司其职的桌面们

作者&#xff1a;旭彦兮沐桌面是只属于我们自己一个人的舞台&#xff0c;是与我们独处的好伙伴。好好布置一下自己的桌面&#xff0c;能在很大程度上保持我们心情的愉悦和做事情的效率&#xff0c;让我们保持专注当下的沉浸感。我最早了解到「桌面文化」其实是很早之前了&#…