一个按值插入 dp 的做法,感觉更好想到。
把 中的元素从大到小依次插入到 dp 中。设 表示当前数组中有 的值,局部最大值的期望是多少。那么显然有初始值 。设当前要转移 ,那么考虑 这个值插入到由 组成的排列会带来的贡献:共有 种不同的插入方案,其中若 插入到了排列的开头,则其会在原来排列的基础上额外带来 的贡献,否则其不会带来额外的贡献。因此有 simple 的 dp 转移式:。
改写上面的 dp 形式得到 ,即 。该式为调和级数形式,记作 ,其有近似公式 ,其中 为欧拉-马歇罗尼常数,近似为 。 的值随 增大呈减小的趋势,当 时值远远小于精度要求 ,而若 直接 递推即可。
// #pragma GCC optimize(3, "Ofast", "inline", "unroll-loops")
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 10000010;
double f[N];
signed main() {
cin.tie(0)->sync_with_stdio(false);
cout << fixed << setprecision(8);
int n;
cin >> n;
if (n < N) {
for (int i = 1; i <= n; ++i) f[i] = f[i - 1] + 1. / i;
cout << f[n] << '\n';
} else {
cout << log(n) + 0.57721566490153286060651209 << '\n';
}
return 0;
}
喜欢的话,留下你的评论吧~