C++写运动会开了N天,一共发出金牌M枚。第1天发金牌1枚加剩下的七分之一枚,第2天发金牌2枚加剩下的七分之一枚,第3天发金牌3枚加剩下的七分之一枚,以后每天都照此办理。到了第N天刚好还有金牌N枚,到此金牌全部发完。请设计递归算法求N和M
时间: 2024-10-21 14:06:54 浏览: 21
这是一个经典的动态规划问题,可以用递归来解决。我们可以定义一个函数`findDaysAndMedals(int M)`,其中`M`代表总金牌数,这个函数的目标是返回一个元组`(days, totalGoldGivenOut)`,表示需要的天数和已经颁发的金牌总数。
递归逻辑如下:
1. 如果剩余金牌数`M`等于0,说明已经颁发了所有的金牌,天数就是当前日期,所以返回`(N, N)`,因为到了第N天恰好颁发了所有金牌。
2. 如果`M`大于0,表示还未颁发完所有金牌,那么在第`i+1`天(从1开始计数),首先颁发`i`枚金牌,然后剩下`M-i`枚,按照题目描述,第二天会颁发剩余金牌的七分之一,即`(M-i)/7`。因此,我们先递归地计算在第`i+1`天前能颁发多少金牌(`totalGoldGivenOut`), 然后加上`i`枚,最后再加上`totalGoldGivenOut`与`(M-i)/7`之和作为新的剩余金牌数`newM`,并加上一天,递归调用自身 `(findDaysAndMedals(newM))`,直到剩余金牌数为0。
递归公式可以写成:
```cpp
if (M == 0) {
return {N, N};
} else {
int i = 1;
int goldGivenThisDay = i;
int newM = M - i + (M - i) / 7; // 计算下一天剩余金牌
auto [daysSoFar, totalGoldGivenOut] = findDaysAndMedals(newM);
return {daysSoFar + 1, totalGoldGivenOut + goldGivenThisDay};
}
```
由于递归涉及到大量重复计算,实际编写时可以使用记忆化技术(如动态规划数组或自底向上的迭代方法)来优化性能。
阅读全文