OJ 递归反推 桃子问题
题目:桃子问题(反推初始桃子数)
链接: https://oj.haizeix.com/problem/184##
路飞买了一堆桃子不知道个数。第 1 天吃了剩下的一半又多吃 1 个;以后每天都吃剩下的一半又多吃 1 个。到第 n 天只剩下 1 个桃子。求最开始有多少个桃子。
输入
- 一个整数 n(2 ≤ n ≤ 30)
输出
- 初始桃子数(正整数)
样例
- 输入:
2
→ 输出:4
- 输入:
3
→ 输出:10
思路(反推法)
设第 k 天开始时的桃子数为 a_k
,题意是第 n 天开始时 a_n = 1
。根据每天的吃法:
- 第 k 天吃掉一半并多吃 1 个,剩下的是下一天开始的数量
a_{k+1}
,关系为: a_{k+1} = a_k - (a_k/2 + 1) = a_k/2 - 1
我们要从 a_n = 1
反推 a_{n-1}, a_{n-2}, ..., a_1
。把等式变形:
- a_{k+1} = a_k/2 - 1 ⇒ a_k/2 = a_{k+1} + 1 ⇒ a_k = 2 * (a_{k+1} + 1)
因此,从后往前递推:
- 初始:a_n = 1
- 对 i 从 n-1 到 1:a_i = 2 * (a_{i+1} + 1)
最终输出 a_1。
推导例子
- n = 2:
- a_2 = 1
- a_1 = 2 * (1 + 1) = 4
- n = 3:
- a_3 = 1
- a_2 = 2 * (1 + 1) = 4
- a_1 = 2 * (4 + 1) = 10
复杂度
- 时间复杂度:O(n)
- 空间复杂度:O(1)
C++ 实现(示例代码)
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
if (!(cin >> n)) return 0;
long long a = 1; // a_n = 1
for (int i = n - 1; i >= 1; --i) {
a = 2 * (a + 1);
}
cout << a << "\n";
return 0;
}
Python 实现(示例代码)
n = int(input().strip())
a = 1 # a_n = 1
for _ in range(n - 1):
a = 2 * (a + 1)
print(a)
你可以将上面的任意一段代码复制到对应语言的编译器/解释器中运行。若需要 Java、Pascal 或其他语言的实现,我可以继续补充。