(概率期望)
小学生一发
一道和概率以及期望有关的题目,硬是磨了一下午才写出来,呜呜呜。
炮台实验
题目描述:
蒜头君在玩一个战争模拟游戏,他有高度为1, 2, 3, …, n 的炮台各一个,他需要把这n个炮台从左往右排成一行,并且炮口都朝向右边。
在这个游戏中,所有炮台发射的炮弹会摧毁前方所有高度比自己低的炮台。每当蒜头君把n个炮台排成一行后,可能会有一些炮台被摧毁。举个例子:当前有5个炮台,从左到右高度分别为2, 1, 3, 5, 4, 往右发射炮弹后,高度为4的炮台被高度为5的摧毁,高度为1的炮台被高度为2的炮台摧毁,最后只会剩下2, 3, 5这三个炮台。
现在蒜头君想知道,如果随机地摆放这n个炮台,最后剩下炮台个数的期望是多少?比如 n=2 时,有两种摆放方式,高度序列分别为1, 2和2, 1, 前者最后剩下2个炮台,后者最后剩下一个炮台,因此期望为(2+1)/2=1.5000。
输入:
一行一个整数n, 表示炮台的数量。(n<=2019)
输出:
输出剩下炮台的期望数量,保留4位小数。
解析
这道题其实很简单,但一开始不知道怎么的,可能是脑子抽了,想了很多办法逗觉得巨麻烦。还好最后柳暗花明又一村。可以这样想,题目是要求最后剩下炮台数的期望,那么我们就可以直接对每个炮台进行考虑,考虑每个炮台存活下来的概率Pi, 然后把所有炮台存活的概率相加即答案为: ∑ i = 1 n P i \sum_{i=1}^{n} P_i ∑i=1nPi . 在计算每个炮台存活概率时, 可以考虑从大到小依次计算,小的数只需考虑他放在所有比他大的数的前面的概率就行。这个概率显然为 1 k \frac{1}{k} k1, (k为大于等于这个数的数量)。
AC代码:
// 小学生一发的刷题之路
// 概率期望
//
//
//
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <deque> //双向队列;
#include <cmath>
#include <set>
#include <stack>
#include <map>
#include <vector>
#include <cstdlib>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const double PI=acos(-1.0);
const double eps=1e-8;
const double e=exp(1.0);
const int maxn=5e5+5;
const int maxm=1e6+5;
const ll mod=1e9+7;
const int INF=1e8;
template<class T>
void read(T &ret){ //快速输入模版;
ret=0;
int f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
ret=ret*10+c-'0';
c=getchar();
}
ret*=f;
}
int main()
{
double n;
scanf("%lf",&n);
double ans=0.0,i=1.0;
while(i<=n){
ans+=1.0/i;
i=i+1.0;
}
printf("%0.4lf\n",ans);
return 0;
}
新的开始,每天都要快乐哈。