当前位置: 首页 > news >正文

代码随想录算法训练营Day35

卡码网46.携带研究材料
力扣494.目标和【meidum】
力扣416.分割等和子集【medium】

一、卡码网46.携带研究材料

题目链接:卡码网46.携带研究材料
在这里插入图片描述
视频链接:代码随想录
题解链接:代码随想录

1、思路

  • 在这里插入图片描述

  • 在这里插入图片描述

  • 在这里插入图片描述

  • dp[i][j] 表示从下标为 [0-i] 的物品里任意取,放进容量为 j 的背包,价值总和最大是多少

  • 状态转移方程 : d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − w e i g h t [ i ] ] + v a l u e [ i ] ) dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]) dp[i][j]=max(dp[i1][j],dp[i1][jweight[i]]+value[i])

  • 在这里插入图片描述

  • 时间复杂度: O ( M ∗ N ) O(M * N) O(MN)

2、代码

import sys
def main():data = sys.stdin.read().strip().split()ptr = 0M = int(data[ptr])ptr += 1N = int(data[ptr])ptr += 1weight = list(map(int,data[ptr : ptr + M]))ptr += Mvalue = list(map(int, data[ptr : ptr + M]))dp = [[0] * (N + 1) for _ in range(M)]for j in range(weight[0], N + 1):dp[0][j] = value[0]for i in range(1,M):for j in range(N + 1):if j < weight[i]:dp[i][j] = dp[i - 1][j]else:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])print(dp[M - 1][N])if __name__ == "__main__":main() 

3、代码问题

  • map() 是一个内置函数,它的作用是将一个函数应用到可迭代对象(如列表、元组等)的每个元素上,并返回一个迭代器。
  • 模板
import sysdef solve():# 读取所有输入并分割data = sys.stdin.read().split()ptr = 0# 按需读取数据n = int(data[ptr])ptr += 1m = int(data[ptr])ptr += 1arr = list(map(int, data[ptr:ptr+n]))ptr += n# 计算逻辑result = sum(arr) * m# 输出结果print(result)if __name__ == "__main__":solve()

二、力扣494.目标和【meidum】

题目链接:力扣494.目标和

在这里插入图片描述
视频链接:代码随想录
题解链接:灵茶山艾府

1、思路

  • 在这里插入图片描述

  • 时间复杂度: O ( m n ) O(mn) O(mn)其中 n n n n u m s nums nums的长度, m m m n u m s nums nums 的元素和减去 t a r g e t target target 的绝对值。

  • 由于每个状态只会计算一次,动态规划的时间复杂度 = 状态个数 × 单个状态的计算时间。

  • 本题状态个数等于 O ( n m ) O(nm) O(nm),单个状态的计算时间为 O ( 1 ) O(1) O(1),所以动态规划的时间复杂度为 O ( n m ) O(nm) O(nm)

  • 空间复杂度: O ( n m ) O(nm) O(nm)。保存多少状态,就需要多少空间。

2、代码

class Solution:def findTargetSumWays(self, nums: List[int], target: int) -> int:# p + q = s = sum(nums)# p - q = target# 故:p = s + target / 2;q = s - target / 2s = sum(nums) -  abs(target)if s < 0 or s % 2:return 0m = s // 2@cachedef dfs(i:int, c:int) -> int: # 表示从前i个数中选一些数恰好组成c的 方案数目if i < 0:return 1 if c == 0 else 0if c < nums[i]:return dfs(i - 1, c)return dfs(i - 1, c) + dfs(i - 1, c - nums[i])return dfs(len(nums) - 1, m)
  • 1:1 翻译成递推
  • 时间空间复杂度和回溯+记忆搜索一致
class Solution:def findTargetSumWays(self, nums: List[int], target: int) -> int:# p + q = s = sum(nums)# p - q = target# 故:p = s + target / 2;q = s - target / 2s = sum(nums) -  abs(target)if s < 0 or s % 2:return 0m = s // 2n = len(nums)f = [ [0] * (m + 1) for _ in range(n + 1)]f[0][0] = 1for i, x in enumerate(nums):for c in range(m + 1):if c < x:f[i + 1][c] = f[i][c]else:f[i + 1][c] = f[i][c] + f[i][c - x]return f[n][m]
  • 空间优化:1个数组
  • 时间复杂度: O ( n m ) O(nm) O(nm),其中 n n n n u m s nums nums 的长度, m m m n u m s nums nums 的元素和减去 t a r g e t target target 的绝对值。
    空间复杂度: O ( m ) O(m) O(m)
class Solution:def findTargetSumWays(self, nums: List[int], target: int) -> int:# p + q = s = sum(nums)# p - q = target# 故:p = s + target / 2;q = s - target / 2s = sum(nums) -  abs(target)if s < 0 or s % 2:return 0m = s // 2f = [1] + [0] * mfor x in nums:for c in range(m, x - 1, -1):f[c] += f[c - x]return f[m]

三、力扣416.分割等和子集【medium】

题目链接:力扣416.分割等和子集
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/56b54b4af52842bdbea42633a16b5980.png#pic_ left =x300)
视频链接:代码随想录
题解链接:灵茶山艾府

1、思路

  • s = s u m ( n u m s ) s = sum(nums) s=sum(nums),找出子集和为 s 2 \frac{s}{2} 2s
  • n u m s nums nums中选出一个子序列,其元素和为 s 2 \frac{s}{2} 2s
  • d f s ( i , j ) dfs(i,j) dfs(i,j):从 n u m s [ 0 ] nums[0] nums[0] n u m s [ i ] nums[i] nums[i] 中恰好选出 = j 的子序列
  • 时间复杂度: O ( n ∗ s 2 ) O(n * \frac{s}{2} ) O(n2s)

2、代码

回溯 + 缓存器 = 记忆化搜索
  • 时间复杂度: O ( n ∗ s 2 ) O(n * \frac{s}{2} ) O(n2s)
  • 空间复杂度: O ( n ∗ s 2 ) O(n * \frac{s}{2} ) O(n2s)
class Solution:def canPartition(self, nums: List[int]) -> bool:@cachedef dfs(i:int, j:int) -> bool:if i < 0:return j == 0return j >=nums[i] and dfs(i - 1, j - nums[i]) or dfs(i - 1, j)s = sum(nums)return s % 2 == 0 and dfs(len(nums)- 1, s)
翻译成递推
  • 为了边界条件,所有的 i 都 + 1处理
  • 构造 ( n + 1 ) ∗ ( s + 1 ) (n+1) * (s+1) (n+1)(s+1)矩阵
  • 时间复杂度: O ( n ∗ s 2 ) O(n * \frac{s}{2} ) O(n2s)
  • 空间复杂度: O ( n ∗ s 2 ) O(n * \frac{s}{2} ) O(n2s)
class Solution:def canPartition(self, nums: List[int]) -> bool:s = sum(nums)if s % 2:return Falses //= 2n = len(nums)f = [[False] * (s + 1) for _ in range(n + 1)]f[0][0] = Truefor i, x in enumerate(nums):for j in range(s + 1):if j >= x and f[i][j - x]:f[i + 1][j] = Trueelse:f[i + 1][j] = f[i][j]return f[n][s]
空间优化
  • 逆序排序:避免正序的重复计数
  • s 2 = m i n ( s 2 + x , s ) s_2 = min(s_2 + x , s) s2=min(s2+x,s)
    • s 2 + x < = s s_2 + x <= s s2+x<=s:即使加上x,当前的总和最多到达 s2 + x ,所以s2 + x 到 s 这个范围是达不到的,不用做无用的计算,默认是 False
    • s 2 + x > s s_2 + x > s s2+x>s:我们的目标是 s ,超过的部分不用检查
  • 在这里插入图片描述
  • 时间复杂度: O ( n ∗ s 2 ) O(n * \frac{s}{2} ) O(n2s)
  • 空间复杂度: O ( s 2 ) O( \frac{s}{2} ) O(2s)
class Solution:def canPartition(self, nums: List[int]) -> bool:s = sum(nums)if s % 2:return Falses //= 2f = [True] + [False] * ss2 = 0for i, x in enumerate(nums):s2 = min(s2 + x, s)for j in range(s2, x - 1, -1):f[j] = f[j] or f[j - x]if f[s]:return Truereturn False

http://www.xdnf.cn/news/154873.html

相关文章:

  • 3、初识RabbitMQ
  • Java学习手册:常用的内置工具类包
  • 35-疫苗预约管理系统(微服务)
  • Jetpack Room 使用详解(下)
  • chrony服务器(1)
  • 我是如何用AI编程制作一个AI表情包生成的小程序
  • 【AI论文】DreamID:基于高保真和快速扩散的三元组ID组学习的人脸交换
  • Ragflow新建的知识库完成后刷新却没有显示,报错MethodNotAllowed: 405 Method Not Allowed:
  • 1软考系统架构设计师:第一章系统架构概述 - 超简记忆要点、知识体系全解、考点深度解析、真题训练附答案及解析
  • TC3xx学习笔记-UCB BMHD使用详解(一)
  • 多个请求并行改造
  • 使用 AFL++ 对 IoT 二进制文件进行模糊测试 - 第一部分
  • Ubuntu20.04部署Dify(Docker方式)
  • 顶点着色器和片元着色器染色+表面体着色器染色
  • 深入理解算力:从普通电脑到宏观计算世界
  • MySQL长事务的隐患:深入剖析与解决方案
  • 【Castle-X机器人】二、智能导览模块安装与调试
  • 【Castle-X机器人】四、智能机械臂安装与调试
  • 【C++】stack、queue和priority_queue的模拟实现
  • Android Compose 框架图像修饰深度剖析:从源码到实践(八)
  • ‌MySQL 事务隔离级别详解
  • 深入剖析 Vue 组件:从基础到实践
  • 5G融合消息PaaS项目深度解析 - Java架构师面试实战
  • Linux文件操作命令终极指南:从查看到高级搜索
  • 使用MobaXterm远程登录Ubuntu系统:SSH服务配置教程
  • 【Docker项目实战】使用Docker部署Caddy+vaultwarden密码管理工具(详细教程)
  • 【Linux网络】打造初级网络计算器 - 从协议设计到服务实现
  • 模态链:利用视觉-语言模型从多模态人类视频中学习操作程序
  • 有关图的类型的题目(1)
  • Linux下终端命令行安装常见字体示例