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

豆包 LeetCode 3082. 求出所有子序列的能量和 Java实现

LeetCode 3082 · 求出所有子序列的能量和

📌 题意理解

数组的能量= 其内部和等于 k 的子序列的个数

要你求:nums 的所有子序列各自的能量,加起来是多少(mod 1e9+7)。

本质上是「子序列的子序列」计数问题——对每个候选子序列 S(sum(S)=k),它会出现在多少个 nums 的大子序列 T 里?


💡 核心转换(关键洞察)

假设有一个确定的子序列S ⊆ nums,sum(S) = k,|S| = len

nums 中不包含在 S 里的元素n - len个,每个可选可不选地塞进 T 里,所以:

S 对答案的贡献 = 2^(n - |S|)

因此:

\text{ans} = \sum_{\substack{S \subseteq \text{nums} \\ \text{sum}(S) = k}} 2^{\,n - |S|}

提出 2ⁿ,等价于追踪每个和为 k 的子序列的2^(-|S|)权重和。


🔑 DP 设计

dp[j]= 已处理元素中,所有和为 j的子序列对应的2^(-len)的累积和。

  • 初始:dp[0] = 1(空子序列,sum=0,len=0 → 2⁰=1)

  • 处理每个数x时:

    • 不选 x:已有子序列仍可存在,且剩余"自由位"多了一位 → 所有 dp 值×2

    • 选 x:从dp[j-x]转移过来,选了 x 后长度 +1 → 相当于原来的贡献× ½,即加上dp_old[j-x]

inv2表示 2 的模逆(MOD+1)/2 = 500000004

状态转移(一维优化,从后往前)

dp_new[j] = dp_old[j] × 2 ← 不选 x + (j≥x ? dp_old[j-x] : 0) ← 选 x(贡献不变,因为 ×2 和 ×½ 抵消的视角)

实际更干净的形式直接用乘法:

dp[j] = dp[j] \times 2 + (j \ge x ? dp[j-x] : 0)

✅ Java 实现

版本一:一维 DP(推荐,O(n·k) 时间,O(k) 空间)

class Solution { public int sumOfPower(int[] nums, int k) { final int MOD = 1_000_000_007; int n = nums.length; // dp[j] = 所有和为 j 的子序列的累计贡献 // 最终 dp[k] 就是答案 long[] dp = new long[k + 1]; dp[0] = 1; // 空子序列 for (int x : nums) { // 必须从后往前遍历(0-1背包) for (int j = k; j >= 0; j--) { // 不选 x:原有方案依然存在,贡献 ×2(x成了"自由元素") dp[j] = (dp[j] * 2) % MOD; // 选 x:从和为 j-x 的状态扩展过来 if (j >= x) { dp[j] = (dp[j] + dp[j - x]) % MOD; } } } return (int) dp[k]; } }

版本二:二维 DP(更好理解,O(n·k) 空间)

class Solution { public int sumOfPower(int[] nums, int k) { final int MOD = 1_000_000_007; int n = nums.length; // dp[i][j] = 从前 i 个元素中,选出和为 j 的子序列的总贡献 int[][] dp = new int[n + 1][k + 1]; dp[0][0] = 1; // 空子序列 for (int i = 1; i <= n; i++) { int x = nums[i - 1]; for (int j = 0; j <= k; j++) { // 不选 nums[i-1]:之前的贡献还在,且多了一个自由位 → ×2 dp[i][j] = (int)((dp[i - 1][j] * 2L) % MOD); } for (int j = x; j <= k; j++) { // 选 nums[i-1]:锁定在子序列内,不加自由位,直接累加 dp[i][j] = (dp[i][j] + dp[i - 1][j - x]) % MOD; } } return dp[n][k]; } }

🔍 用示例走一遍

nums = [1,2,3], k = 3,答案为6

和为 3 的子序列 SS贡献 = 2^(3-S)
[3]12² = 4
[1,2]22¹ = 2
合计6

⏱️ 复杂度

时间空间
二维O(n·k)O(n·k)
一维优化O(n·k)O(k)

约束n ≤ 100, k ≤ 100,完全轻松跑过 🎯

这道题本质是带贡献系数的 0-1 背包,难点在于想到把"所有子序列的能量和"转换成"每个 sum=k 的子序列被多少个大子序列包含"——一旦转过弯来,就是标准背包模板了。

http://www.jsqmd.com/news/973460/

相关文章:

  • 3分钟掌握百度网盘直链解析:告别限速的完整指南
  • 手把手教你排查华为桌面云FusionAccess用户登录失败问题(附详细日志分析)
  • 终极游戏语言障碍终结者:XUnity.AutoTranslator完整指南
  • 【Redis分布式缓存实战】第18章 Redis全方位性能调优
  • 第33章:AI辅助SocialFi开发——Lens协议集成
  • IDEA + Maven Assembly Plugin:一条命令打包含所有依赖的JavaFX Jar,再用exe4j生成轻量exe
  • 广元母婴除甲醛CMA甲醛检测治理公司深度测评:绿呼吸环保稳居榜首 - 一修哥咨询
  • 赣州母婴除甲醛CMA甲醛检测治理公司深度测评:绿呼吸环保稳居榜首 - 一修哥咨询
  • PHP代码迁移与版本升级指南
  • 可形变模型原理与实战:从PCA降维到足部三维参数化建模
  • 手把手教你用RT-Thread点亮CH32V307开发板的LED,并搞定串口打印(附完整工程)
  • B站光科教程之外:Light Tools新手快速上手的5个隐藏技巧和界面冷知识
  • 别再只测平面了!手把手教你用Apriltag和Homography矩阵实现3D姿态解算
  • PID无线调参进阶:基于HC-05蓝牙和SerialPlot,打造你的移动调试工作站
  • 拒绝暴力洗稿!2026年实测横评10款免费降AI工具:搞定去AIGC痕迹与学术表达双标准 - 降AI实验室
  • 富阳母婴除甲醛CMA甲醛检测治理公司深度测评:绿呼吸环保稳居榜首 - 一修哥咨询
  • AI生成excel表格“AI导出鸭”:结构化数据流转的深度测评与工程实证
  • 2026年众智商学院PMP班期确认加微信怎么问?官网400冯老师考前冲刺咨询 - 众智商学院职业教育
  • RAGFlow 使用指南:从部署到构建 AI 知识库
  • 第35章:AI辅助开发者工具——自动生成ABI文档与TypeScript类型
  • Android启动安全实战:手把手教你用avbtool给dtbo.img镜像签名(附完整命令)
  • 2026电脑显示器选购:高端方案解析与避坑指南 - 服务品牌热点
  • 阜新母婴除甲醛CMA甲醛检测治理公司深度测评:绿呼吸环保稳居榜首 - 一修哥咨询
  • 深度解锁NVIDIA显卡潜能:Profile Inspector完全使用手册
  • 多 SIM 协作 (DSDS/DSDA) 架构文档
  • 如何快速从科研图表中提取数据:WebPlotDigitizer完整指南
  • 深入理解JavaScript执行机制:从执行上下文到调用栈,八个代码示例彻底搞懂变量提升和作用域
  • 哪家钢格板厂家专业?2026年6月推荐TOP5对比项目防腐蚀评测案例适用场景 - 品牌推荐
  • AI幻觉不是Bug,而是智能体的预测性编码本能
  • GPT-4的1.8万亿参数与2%激活真相:MoE路由机制深度解析