欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 产业 > 序列dp常见思路总结

序列dp常见思路总结

2025/5/17 23:22:05 来源:https://blog.csdn.net/weixin_74850661/article/details/148015641  浏览:    关键词:序列dp常见思路总结

文章目录

  • 习题
    • 选或不选
      • 494.目标和
    • 枚举哪一个
      • 300.最长递增子序列

  • 序列dp是常考的题型,那么我们我们可以根据什么将它们分类,然后对于不同的类型的题目使用对应的模版进行求解?
  • 首先,子序列不同于子数组,子数组是要求元素在原来的序列当中是连续的,而子序列的元素不要求在原来的序列当中是连续的
  • 总的来说,子序列dp问题主要是两种套路

选或不选

  • 当面对是 子序列+相邻元素无关,也就说当面对当前的元素nums[i]的时候,并没有相邻元素之间的限制的条件,也就是都可以选,所以可以采用的是 选或不选的策略
  • 常常使用0-1背包问题模版进行求解

枚举哪一个

  • 当面对子序列+相邻元素相关,也就是对于原来的元素,我们在选择的时候,存在限制条件,那么我们就需要考虑枚举哪一个
  • 当然,代表问题当然是最长递增子序列,在定义的时候,我们常常需要定义dp[i]为以nums[i]结尾的情况的最值或者方案数

习题

选或不选

494.目标和

494.目标和

在这里插入图片描述
在这里插入图片描述

  • 思路分析:由于选择的元素,在原来的序列当中,并没有限制条件,所以我们就直接使用选或不选,在这题当中,我们通过转化,可以求解正的数或者负的数的和为目标值的问题,考虑使用0-1背包的模版进行求解
class Solution:def findTargetSumWays(self, nums: List[int], target: int) -> int:# 子序列问题,相邻元素之间并没有过多的要求# 根据式子,我们只需找出正数的和为 (sum(nums) + target)//2n = len(nums)p = sum(nums) + target # 这里我们求解正的数和为tarif p < 0 or p % 2 == 1:return 0 tar = p // 2 # 这个就可以转化为0-1背包问题# dp[i][j]表示前i个物体中,选中为j的方案数dp = [[0]*(tar+1) for _ in range(n+1)]dp[0][0] = 1 for i in range(n):for j in range(tar+1):if j < nums[i]:dp[i+1][j] = dp[i][j]else:dp[i+1][j] = dp[i][j] + dp[i][j-nums[i]]return dp[n][tar]

枚举哪一个

300.最长递增子序列

300.最长递增子序列

在这里插入图片描述

在这里插入图片描述

  • 思路分析:最长递增子序列模版题目,首先为了更好理解这个枚举哪一个,我们使用o(n^2)的时间复杂度的进行求解,当然后面也可以使用线段树进行优化为o(nlogn)的复杂度
class Solution:def lengthOfLIS(self, nums: List[int]) -> int:# 首先最简单的情况,当然是考虑o(n^2)的时间复杂度的算法n = len(nums)# 定义dp[i]为以nums[i]结尾的最大递增子序列的长度dp = [1]*n # dp[i] = max(dp[j]) + 1,并且 nums[i] > nums[j] , j < i for i in range(1,n):for j in range(i):if nums[i] > nums[j] and dp[i] < dp[j] + 1:dp[i] = dp[j] + 1return max(dp)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词