收集邮票 题解

本文网址:https://www.cnblogs.com/zsc985246/p/16366647.html ,转载请注明出处。

题目大意

有 $ n $ 种不同的物品,每天可以买一个,物品随机第 $ i $ 天需要付 $ i $ 元钱,求买到所有物品的期望钱数。

输入

一个数, $ n $ 。

输出格式

期望要付多少钱,保留 $ 2 $ 位小数

思路

第 $ i $ 天需要付 $ i $ 元钱,考虑先求出期望需要多少天能买到所有物品。

设 $ day[i] $ 为手中有 $ i $ 种物品的期望天数。

考虑当前买了 $ i $ 张物品,再买一个物品,有两种情况:

  1. 有 $ \frac{i}{n} $ 的概率买到重复的物品,此时仍只买到 $ i $ 个物品;即 $ \frac{i}{n} \times day[i] $

  2. 有 $ \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 $ ,逆推求结果。

现在我们只有天数的期望,但是求的是钱数的期望。

  1. 若买到重复的物品,往后推了一天,所以总价格要多 $ day[i] $ 元,还要加上增加的 $ 1 $ 元。即: $ \frac{i}{n} \times ( f[i] + day[i] + 1 ) $

  2. 若买到没买过的物品,也往后推了一天,所以总价格要多 $ 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[i] = \frac{i}{n} \times ( f[i] + day[i] + 1 ) + \frac{n-i}{n} \times ( f[i+1] + day[i+1] + 1 )\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\ \ \ \ \ \ \ \ \ \ \ \ \ = \frac{i}{n} \times f[i] + \frac{i}{n} \times day[i] + \frac{i}{n} + \frac{n-i}{n} \times f[i+1] + \frac{n-i}{n} \times day[i+1] + \frac{n-i}{n}\\ \ \ \ \ \frac{n-i}{n} \times f[i] = \frac{i}{n} \times day[i] + \frac{n-i}{n} \times f[i+1] + \frac{n-i}{n} \times day[i+1] + 1\\ =\frac{i}{n-i} \times day[i] + f[i+1] + day[i+1] + \frac{n}{n-i} \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \]

初始 $ 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;
}

尾声

如果你发现了问题,你可以直接回复这篇题解

如果你有更好的想法,也可以直接回复!

posted @ 2022-06-11 19:47  zsc985246  阅读(254)  评论(0)    收藏  举报