feat:添加欧拉项目第30题和第31题的解决方案

📝 docs:为第31题添加详细的动态规划算法说明文档
This commit is contained in:
2025-12-29 18:18:10 +08:00
parent 25469e1022
commit 8ee312ac1d
3 changed files with 232 additions and 0 deletions

114
solutions/0031/readme.md Normal file
View File

@@ -0,0 +1,114 @@
# 动态规划法
## 核心思路
这个函数采用**动态规划**的思想,通过构建一个 `ways` 数组来累积计算每个金额对应的方法数。
---
## 逐行解析
### 1. 初始化
```python
coins = [1, 2, 5, 10, 20, 50, 100, 200]
ways = [1] + [0] * 200 # 结果是 [1, 0, 0, 0, ..., 0] (共201个元素)
```
- `coins`: 所有可用的硬币面值(单位:便士)
- `ways[i]`: 表示凑成金额 `i` 的方法数
- **关键点**`ways[0] = 1` 表示凑成0元有1种方法什么都不用这是动态规划的**基准条件**
### 2. 双重循环的核心逻辑
```python
for coin in coins: # 按顺序遍历每种硬币
for i in range(coin, 201): # 从当前硬币面值遍历到200
ways[i] += ways[i - coin]
```
这就是**状态转移方程**,其含义是:
> **凑成金额 `i` 的方法数 = 原来方法数 + 使用当前硬币的方法数**
其中 `ways[i - coin]` 表示在使用了1枚当前硬币后凑齐剩余金额的方法数。
---
## 具体执行过程演示
让我们跟踪计算前几个值的变化,以理解算法如何工作:
### 初始状态
```
ways = [1, 0, 0, 0, 0, 0, ...] # ways[0]=1
```
### 第1轮使用硬币 1p
```python
for i in range(1, 201):
ways[i] += ways[i-1]
```
- `i=1`: `ways[1] += ways[0]``0 + 1 = 1` ✓ 凑1p: {1}
- `i=2`: `ways[2] += ways[1]``0 + 1 = 1` ✓ 凑2p: {1,1}
- `i=3`: `ways[3] += ways[2]``0 + 1 = 1` ✓ 凑3p: {1,1,1}
- ...
- **结果**只用1p硬币每个金额都有且仅有1种方法
### 第2轮加入硬币 2p
```python
for i in range(2, 201):
ways[i] += ways[i-2]
```
关键更新点:
- `i=2`: `ways[2] += ways[0]``1 + 1 = 2`
- 原来:{1,1}
- 新增:{2}
- `i=3`: `ways[3] += ways[1]``1 + 1 = 2`
- 原来:{1,1,1}
- 新增:{1,2}
- `i=4`: `ways[4] += ways[2]``1 + 2 = 3`
- 原来:{1,1,1,1}
- 新增:{1,1,2}, {2,2}
### 第3轮加入硬币 5p
当加入5p硬币后凑5p的方法从1种 {1,1,1,1,1} 变成2种新增 {5}。
**以此类推**,直到处理完所有硬币类型。
---
## 为什么这样计算?
这个算法的精妙之处在于:
1. **按硬币顺序处理**:确保计算的是**组合数**(不考虑顺序)
- {1,2,2} 和 {2,1,2} 视为同一种方法
- 如果调换循环顺序(先金额后硬币),会计算出排列数
2. **累积效应**`ways` 数组保存的是**所有已处理硬币**能凑成的方法总数
3. **避免重复**:每种硬币只被考虑一次在其对应的外层循环中,确保不重复计算
---
## 最终结果
当循环结束后,`ways[200]` 的值就是 200便士能被凑成的所有方法数。
```python
print(f"\nThe number of ways to make £2 is {ways[200]:,d}")
```
输出结果是:**73682**
这意味着用这8种英国硬币凑成2英镑共有**73,682**种不同的方式。
---
## 时间复杂度
- **O(N×M)**:其中 N = 硬币种类数8M = 目标金额200
- 实际计算量约为 8 × 200 = 1600 次操作,效率极高
这个算法简洁优雅,展示了动态规划在组合计数问题中的强大威力。