收集邮票 题解
本文网址:https://www.cnblogs.com/zsc985246/p/16366647.html ,转载请注明出处。
题目大意
有 $ n $ 种不同的物品,每天可以买一个,物品随机,第 $ i $ 天需要付 $ i $ 元钱,求买到所有物品的期望钱数。
输入
一个数, $ n $ 。
输出格式
期望要付多少钱,保留 $ 2 $ 位小数。
思路
第 $ i $ 天需要付 $ i $ 元钱,考虑先求出期望需要多少天能买到所有物品。
设 $ day[i] $ 为手中有 $ i $ 种物品的期望天数。
考虑当前买了 $ i $ 张物品,再买一个物品,有两种情况:
-
有 $ \frac{i}{n} $ 的概率买到重复的物品,此时仍只买到 $ i $ 个物品;即 $ \frac{i}{n} \times day[i] $
-
有 $ \frac{n-i}{n} $ 的概率买到没买过的物品,此后就已买到 $ i+1 $ 个物品。即 $ \frac{n-i}{n} \times day[i+1] $
但是两种情况都多了一天,所以 $ day[i] = \frac{i}{n} \times day[i] + \frac{n-i}{n} \times day[i+1] + 1 $ 。
化简一下:
$ day[i] = \frac{i}{n} \times day[i] + \frac{n-i}{n} \times day[i+1] + 1 $
$ \frac{n-i}{n} \times day[i] = \frac{n-i}{n} \times day[i+1] + 1 $
$ day[i] = day[i+1] + \frac{n}{n-i} $
初始 $ day[n] = 0 $ ,逆推求结果。
现在我们只有天数的期望,但是求的是钱数的期望。
-
若买到重复的物品,往后推了一天,所以总价格要多 $ day[i] $ 元,还要加上增加的 $ 1 $ 元。即: $ \frac{i}{n} \times ( f[i] + day[i] + 1 ) $
-
若买到没买过的物品,也往后推了一天,所以总价格要多 $ day[i+1] $ 元,还要加上增加的 $ 1 $ 元。即: $ \frac{n-i}{n} \times ( f[i+1] + day[i+1] + 1 ) $
所以 $ f[i] = \frac{i}{n} \times ( f[i] + day[i] + 1 ) + \frac{n-i}{n} \times ( f[i+1] + day[i+1] + 1 ) $
化简一下:
初始 $ f[n] = 0 $ ,逆推求结果。
最后输出 $ f[0] $ 。
代码实现
#include<bits/stdc++.h>
#define ll long long
const ll N=10010;
using namespace std;
ll n;//物品种数
double day[N];//i种物品的期望天数
double f[N];//i种物品的期望钱数
int main(){
cin>>n;
for(ll i=n-1;i>=0;i--){//计算天数
day[i]=day[i+1]+n*1.0/(n-i);//公式
}
for(ll i=n-1;i>=0;i--){//计算答案
f[i]=i*1.0/(n-i)*day[i]+n*1.0/(n-i)+f[i+1]+day[i+1];//公式
}
cout<<fixed<<setprecision(2)<<f[0];
return 0;
}
尾声
如果你发现了问题,你可以直接回复这篇题解
如果你有更好的想法,也可以直接回复!

浙公网安备 33010602011771号