题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4986
题目意思:有 n 个box(从左到右编号依次为1~n),每个box里面有一个随机的钥匙,有可能这条钥匙恰好可以开到这个box,但大多数情况下是不能够的。问期望值是多少。(例如对于两个box,有可能装着1 2 或者 2 1的 key,如果是1 2,那么就需要用两次咒语,而对于2 1(打开其中一个box就可以得到要开到另一个box的钥匙)只需要用一次即可。期望值就是 1/2 * 2 + 1/2 * 1 = 1.5 。1/2 是表示情况数。
据说要用到调和级数的化简,欧拉常数,数论题,留个纪念。真是如果缺乏某些知识点,考数学这些题目是完全不会做的。

#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; typedef __int64 LL; const int maxn = 10000 + 10; const double r = 0.577215664901; // 欧拉常数0.577218; double f[maxn+20]; LL n; int main() { f[1] = 1; for (int i = 2; i <= maxn; i++) f[i] = f[i-1] + (1/(double)i); while (cin >> n) { if (n > 10000) printf("%.4lf ", log((double)n) + r); else printf("%.4lf ", f[n]); } return 0; }