大概这才是期望dpdp的入门题吧.

可以合并当前项的dpdp哦!

首先定义方程fif_i表示已经拿到了ii个,还需要拿多少次能全部拿完的期望.

那么容易得到转移方程:

fi=fi(i/n)+fi+1(1i/n)+1f_i=f_i*(i/n)+f_{i+1}*(1-i/n)+1.

合并同类项可以得到:

fi=fi+1+n/(ni)f_i=f_{i+1}+n/(n-i).

同时定义答案数组ansians_i已经拿了ii个所需钱的期望,那么也可以得到方程.

ansi=(i/n)(ansi+fi)+(1i/n)(ansi+1+fi+1)+1ans_i=(i/n)*(ans_i+f_i)+(1-i/n)*(ans_{i+1}+f_{i+1})+1.

可以理解为提前算好了后面的贡献,使得每件商品的价格变成了11.

也可以合并一下同类项得到:

ansi=i/(ni)fi+ansi+1+fi+1+n/(ni)ans_i=i/(n-i)*f_i+ans_{i+1}+f_{i+1}+n/(n-i).

code:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N=1e4+5;
const int mod=998244353;
const double eps=1e-9;

double f[N],ans[N];

void solve()
{
	int n;
	scanf("%d",&n);
	f[n]=ans[n]=0;
	for(int i=n-1;i>=0;i--)
		f[i]=f[i+1]+(double)n/(double)(n-i);
	for(int i=n-1;i>=0;i--)
		ans[i]=(double)i/(double)(n-i)*f[i]+ans[i+1]+f[i+1]+(double)n/(double)(n-i);
	printf("%.2f\n",ans[0]);
}

int main()
{
	int T=1;
//	scanf("%d",&T);
	while(T--)	solve();
	return 0;
}
/*

*/