苹果放盘子问题C++实现:动态规划与记忆化递归详解
## 🍎 问题分析:苹果放盘子(组合计数) 这是一个**经典动态规划/递归**问题,核心是**无序组合**(即顺序无关)。我用 **C++** 实现。 --- ### 🧠 核心思路 设 `f(m, n)` 表示 **m 个苹果放 n 个盘子** 的方法数(允许空盘)。 **递推关系**: - 如果 `m == 0` 或 `n == 1` → 只有 **1** 种方法(无苹果或只有一个盘子)。 - 如果 `m < n` → 空盘至少 `n-m` 个,等价于 `f(m, m)`(去掉空盘)。 - 否则: - **至少一个盘子空着**:`f(m, n-1)` - **每个盘子至少放 1 个苹果**:`f(m-n, n)` 所以递推式: ``` f(m, n) = f(m, n-1) + f(m-n, n) (当 m >= n) ``` --- ### 💻 C++ 实现(动态规划 + 记忆化) ```cpp #include <iostream> #include <cstring> using namespace std; const int MAX = 15; // 题目 m, n 一般很小,可调整 int dp[MAX][MAX]; // 记忆化递归 int f(int m, int n) { // 边界条件 if (m == 0 || n == 1) return 1; // 已计算过 if (dp[m][n] != -1) return dp[m][n]; if (m < n) { // 盘子比苹果多,空盘忽略 dp[m][n] = f(m, m); } else { // 至少一个空盘 + 每个盘子至少放一个 dp[m][n] = f(m, n - 1) + f(m - n, n); } return dp[m][n]; } int main() { int t; cin >> t; while (t--) { int m, n; cin >> m >> n; memset(dp, -1, sizeof(dp)); // 重置记忆化数组 cout << f(m, n) << endl; } return 0; } ``` --- ### 📊 复杂度分析 | 方法 | 时间复杂度 | 空间复杂度 | |------|------------|------------| | 递归+记忆化 | O(m*n) | O(m*n) | | 纯递归(不推荐) | 指数级 | O(深度) | | 动态规划(自底向上) | O(m*n) | O(m) 可优化 | **建议**:由于 m, n 通常 ≤ 10~15,直接用记忆化递归即可。 --- ### 🧪 测试样例 **输入**: ``` 2 7 3 5 5 ``` **输出**: ``` 8 7 ``` **解释**(7,3): - 7=7, 6+1, 5+2, 5+1+1, 4+3, 4+2+1, 3+3+1, 3+2+2 → 共8种。 --- ### ⚠️ 易错点与开发建议 1. **边界条件务必处理**:`m==0` 和 `n==1` 必须返回1,否则递归死循环。 2. **记忆化数组初始化**:使用 `memset(dp, -1, sizeof(dp))`,每次测试重置。 3. **输入规模**:如果 m, n 可能很大(>100),需改用**动态规划二维数组**或**滚动数组**优化空间。 4. **题目提示**:`5,1,1` 和 `1,1,5` 相同,所以不能简单枚举排列,必须用组合计数方法。 --- ### 📚 扩展阅读 - [洛谷 P1025 数的划分](https://www.luogu.com.cn/problem/P1025)(类似思想) - [苹果放盘子 - 博客园详解](https://www.cnblogs.com/dongsheng/archive/2012/08/15/2640451.html) --- ######[AI写代码神器 | 948点数解答 | 2026-07-31 19:52:15]
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)543
- 深度揭秘 Oracle Workarea Size Policy:参数调优助力数据库性能飞升(阿里通义 | 372点数解答 | 2024-05-13 10:54:45)332
- Python编程:解析小明和小李喜欢水果集合的运算奥秘( | 769点数解答 | 2024-04-23 17:32:15)367
- Python 实现:带边界处理与验证的任意基数数字转换递归程序(字节豆包 | 198点数解答 | 2024-11-21 14:20:25)503
- Python 递归函数实现:将数字转换为指定基数的输出(百度文心 | 499点数解答 | 2024-11-22 09:58:55)402
- Python 代码:合并食品与家居清单,巧妙去除重复物品!(字节豆包 | 89点数解答 | 2025-03-13 09:12:59)243
- 编程模拟:偶数张牌经 k 次洗牌后第 p 张牌编号求解(DeepSeek | 126点数解答 | 2026-01-05 12:15:30)90
- 螺旋矩阵:根据输入行列号精准求出对应位置数字的算法揭秘(DeepSeek | 740点数解答 | 2026-01-05 12:16:41)115
- C++实现水果总价计算及开发要点(字节豆包 | 616点数解答 | 2026-05-23 11:45:08)44
- Pygame实现种树游戏:种树、合成与买卖乐趣多(字节豆包 | 2138点数解答 | 2026-06-08 15:39:01)47
- 51 单片机:定时器 0 实现 8 个 LED 循环点亮,附代码及优化建议(字节豆包 | 1193点数解答 | 2024-12-27 15:10:29)461
- 浙闽“板凳龙”舞龙队 300 秒螺线盘入:位置与速度全揭秘(阿里通义 | 886点数解答 | 2024-09-07 10:31:31)719