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

动态规划题解_将一个数字表示成幂的和的方案数【LeetCode】

2787. 将一个数字表示成幂的和的方案数

给你两个整数 n 和 x 。

请你返回将 n 表示成一些 互不相同 正整数的 x 次幂之和的方案数。换句话说,你需要返回互不相同整数 [n1, n2, ..., nk] 的集合数目,满足 n = n1x + n2x + ... + nkx 。

由于答案可能非常大,请你将它对 109 + 7 取余后返回。

比方说,n = 160 且 x = 3 ,一个表示 n 的方法是 n = 23 + 33 + 53 。

示例 1:

输入:n = 10, x = 2
输出:1
解释:我们可以将 n 表示为:n = 32 + 12 = 10 。
这是唯一将 10 表达成不同整数 2 次方之和的方案。

示例 2:

输入:n = 4, x = 1
输出:2
解释:我们可以将 n 按以下方案表示:
- n = 41 = 4 。
- n = 31 + 11 = 4 。

一、算法逻辑(逐步思路)

❓ 题目描述:

给定两个整数 nx,问:
有多少种方法可以用不同的正整数的 x 次幂相加,恰好等于 n

  • 每个整数最多使用一次(不能重复);
  • 返回方案数,结果对 10^9 + 7 取模。

✅ 解析过程:

1. 状态定义:
  • 定义 f[s] 表示和为 s 的组合数目
  • 初始化:f[0] = 1,表示选法为空时和为 0 的唯一方案。
2. 状态转移:
  • 对每个正整数 i,计算它的 x 次幂 v = i^x
  • 使用这个数能更新哪些和 s
    • 遍历 snv(倒序,防止重复使用);
    • 更新方式:f[s] += f[s - v]
      • 意思是:若当前组合中加入一个 v,使得和达到 s,那就看以前有多少种方法能组成 s - v
      • 相当于经典的0/1 背包模型(每个数最多使用一次)。
3. 终止条件:
  • 如果当前的 i^x > n,说明无法再用于任何组合,直接退出。
4. 返回值:
  • f[n] 表示最终组成 n 的合法组合数;
  • 对结果取模是为了防止整数溢出。

二、算法核心点

✅ 核心思想:0/1背包模型上的指数幂优化

  • 每个正整数 i 只能使用一次,对应背包问题中“每种物品最多取 1 次”;
  • 数字 v = i^x 就是物品的“体积”;
  • 每次用 f[s] += f[s - v] 实现状态转移;
  • 为避免重复计算、实现“每个数最多选一次”,必须倒序更新状态数组。

对应题目经典名称:

Perfect Powers Combination Problem(幂次组合计数)

class Solution:def numberOfWays(self, n: int, x: int) -> int:f = [1] + [0] * n  # 初始化DP数组:f[s] 表示组成和为 s 的方案数# 初始状态:f[0] = 1,表示“和为0”的方案就是啥也不选for i in range(1, n + 1):  # 枚举所有底数 i(1 到 n)v = i ** x  # 当前考虑的数是 i 的 x 次幂if v > n:   # 如果这个数太大,跳出循环break# 倒序遍历(0/1背包)从 n 到 vfor s in range(n, v - 1, -1):f[s] += f[s - v]  # 转移方程:将 v 加入组合中,组成 sreturn f[n] % 1_000_000_007  # 返回最终和为 n 的方案数

三、复杂度分析

  • 时间复杂度:O(k × n)
    • k 是最多可以选择的整数个数(即 i 满足 i^x ≤ n);
    • 对每个合法 i,我们进行一次 O(n) 的遍历。
  • 空间复杂度:O(n)
    • 状态数组 f 长度为 n + 1

总结表:

维度

内容

✅ 思路逻辑

将问题转换为组合数问题,用 0/1 背包方式动态转移

✅ 核心技巧

每个数最多用一次(倒序遍历);幂次作为体积;经典 f[s] += f[s - v] 模型

✅ 时间复杂度

O(√n × n) 最多枚举 √n 个底数,每次遍历 n 个状态

✅ 空间复杂度

O(n) 一维 DP 数组

总结思路:

步骤内容
初始化 f[0] = 1和为 0 有 1 种方式(空集)
枚举 i = 1...n将 i 的 x 次幂作为候选数
倒序更新 DP 数组保证每个数最多用一次(0/1背包)
更新 f[s] += f[s - v]表示:新方案 = 旧方案 + 使用 v 的方案
取模避免大数溢出
http://www.lryc.cn/news/587255.html

相关文章:

  • 《夏重庆》——一场暴雨的立体诗篇(DeepSeek赏析)
  • SQL140 未完成率top50%用户近三个月答卷情况
  • Flask中的路由尾随斜杠(/)
  • Kafka——Kafka 线上集群部署方案怎么做?
  • 代理模式:控制对象访问
  • AutoLabor-ROS-Python 学习记录——第二章 ROS通信机制
  • CATIA许可价格高,设计部门如何精细化分配?
  • Python 数据挖掘之数据探索
  • 鸿蒙选择本地视频文件,并获取首帧预览图
  • 【算法】贪心算法:柠檬水找零C++
  • 密码学系列文(1)--密码学基础概念详解
  • 密码学系列文(2)--流密码
  • ansible自动化部署考试系统前后端分离项目
  • 在 C# 中调用 Python 脚本:实现跨语言功能集成
  • MySQL逻辑删除与唯一索引冲突解决
  • C++高频知识点(九)
  • 39.Sentinel微服务流量控制组件
  • 【一起来学AI大模型】部署优化推理加速:vLLM
  • word中多行合一功能实现
  • comfyUI-ControlNet-姿势控制深度控制
  • Java 8 LocalDate 日期操作全攻略
  • CS课程项目设计1:交互友好的井字棋游戏
  • 【多线程】 线程池设多大才合理?CPU 密集型和 I/O 密集型的终极公式
  • 深度学习图像分类数据集—七种树叶识别分类
  • AI生成单词消消乐游戏. HTML代码
  • LeetCode 2401.最长优雅子数组
  • Ampace厦门新能安科技Verify 测评演绎数字推理及四色测评考点分析、SHL真题题库
  • 【sql学习之拉链表】
  • 系规备考论文:论IT服务知识管理
  • MyBatis框架进阶指南:深入理解CRUD与参数映射