luogu1984 [SDOI2008] 烧水问题
题目描述
给出水的比热容、冰点和沸点,问将$n$杯有$\frac{1}{n}\mathrm{kg}$的水从冰点加热到沸点所需最小热量。不一定相邻的两杯水间可以无热量损失地热传递至两者温度相同。
题解
首先,审题!只有两杯水间才可以热传递!不可以三杯水同时热传递!
我们这道题的入手点在于能量守恒定律。我们要让煮沸一杯水的每一个单位热量都尽可能地被用到加热其它没有煮沸的水上,热量能转移,就转移。所以我们要让第一杯水现与第二杯水热传递,再让第一杯水与第三杯水传递,再与第四杯……第二杯加热完后与第三杯、第四杯……传递热量。
由于时间复杂度要求我们在$O(n)$内解决,我们可就必须要找找规律了。
杯子编号 | 初始加热质量来源 | 初始加热质量比例 | 所需加热质量比例$t$ |
1 | 无 | 0 | 1 |
2 | 1→2 | 1/2 | 1/2 |
3 | 1→3+2→3 | 5/8 | 3/8 |
4 | 1→4+2→4+3→4 | 11/16 | 5/16 |
我们有这能找出什么规律呢?因为烧水是热传递,所以我们看看比例。
$\frac{t_2}{t_1}$ | $\frac{1}{2}$ |
$\frac{t_3}{t_2}$ | $\frac{3}{4}$ |
$\frac{t_4}{t_3}$ | $\frac{5}{6}$ |
这样我们就知道了:
$$\frac{t_{n+1}}{t_n}=\frac{2n-1}{2n}$$
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int main() { int n; scanf("%d", &n); double ans = 1, t = 1; for (int i = 2; i <= n; i++) { t = t * (2.0 * (i - 1) - 1) / (2.0 * (i - 1)); ans += t; } printf("%.2f\n", ans * 420000 / n); return 0; }