曾记否,到中流击水,浪遏飞舟。|

Moyyer_suiy

园龄:2年8个月粉丝:4关注:18

10.31 模拟赛小记

抽象场。打完人自闭的那种。

得分情况:8003030


A:从 0 走到 n。在 i 位置时,等概率走的走到 [i+1,n](视为一步)。求期望步数。

哥们赛时,爆搜打表找规律。。。最后写的 O(n),没看到第九个数据点没有特判。对于最后一个点 1e18,递推式写出来但不会进一步求。遗憾离场。

以下是正确的推导过程。

f[i] 表示走到 i 时的期望步数。0<j<i1,让 ij 转移过来,每种可能都为 1/i,最后加上转移的这一步。得到 o(n^2) 的暴力 dp。

#include<bits/stdc++.h>
#define db double
using namespace std;
const int N=1e7+10;
int n;
db f[N];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		for(int j=0;j<i;j++) f[i]+=f[j];
		f[i]=f[i]/i+1;
	}
	printf("%.6lf",f[n]);
}

加上前缀和优化,得到 O(n)

#include<bits/stdc++.h>
#define db double
using namespace std;
const int N=1e7+10;
int n;
db f[N],sum;
int main(){
	scanf("%d",&n); 
	for(int i=1;i<=n;i++){
		f[i]=sum/i+1;
		sum+=f[i]; 
	}
	printf("%.6lf",f[n]);
}

这就 80pts。然后打表特判第九个点。数组存不下,直接用变量。

考虑最后 n<=1e18,肯定有什么规律。大胆猜想:fi=i=1n1i

然后证明:

dpi=1i(j=0i1dpj+1

=1i(j=0i2dpj+dpi1)+1

=1i(j=0i2dpj+(1i1(j=0i2dpj)+1))+1

=1i(ii1j=0i=2dpj+1)+1

=(1i1j=0i2dpj+1)+1i

=dpi1+1i

然后就是调和级数的计算了。调和级数是什么,我也不是很懂,只是知道这样的式子:

Hn=i=1n1i=lnn+γ+εn

γ 为欧拉-马歇尔罗尼常数。约为 0.577215664901532860606512090082

εn 约等于 12n,当 nεm0

因此小范围暴力,大范围输出这个。

#include<bits/stdc++.h>
#define ll long long
#define db double
using namespace std;
ll n;
db sum;
int main(){
	scanf("%lld",&n);
	if(n>5e8){
		printf("%.6lf",log(n)+0.57721566490153286060);
		return 0;
	}
	for(int i=1;i<=n;i++) sum+=1.0/i;
	printf("%.6lf",sum);
}

注意 c++ 中 log() 默认是数学中的 ln(),以 2 为底是 lg2(),以 10 为底是 lg10()。

本文作者:Moyyer_suiy

本文链接:https://www.cnblogs.com/Moyyer-suiy/p/17801592.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Moyyer_suiy  阅读(23)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起