概率与期望-题目与解答

擅长解密的小红同学

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网

题目描述

小红来到了一个机关前,准备破解机关的密码门。

已知机关的密码是一串数字('0'~'9')。小红经过不懈的努力,终于破解了每个数字出现的次数。但她并不知道每个数字出现的先后次序。

于是她只能随机来尝试破解密码。不过这个机关有个特点:每当小红输入一次尝试之后,密码都会重置。不过每个数字出现的次数不变。

小红想知道自己尝试次数的期望是多少?

输入描述:

一行共 10 个非负整数 aia_iai​ ,分别代表 '0'~'9' 每个数字的出现次数。

0≤ai≤10^6 ,且保证所有 aia_iai​ 不会全为0。

输出描述:

小红尝试次数的期望,对 10^9 + 7取模。

可以证明,该期望一定为有理数。如果该期望为分数,请输出分数取模的值。

分数取模的定义: x/y mod p=a ,等价于 a∗y mod p=x

示例1

输入

0 2 0 0 0 0 0 0 0 0

输出

1

说明

已知数字 1 出现了 2 次,那么密码只有可能是 "11" ,小红只需要一次输入即可破解。

示例2

输入

1 1 0 0 0 0 0 0 0 0

输出

2

说明

已知数字 0 出现了 1 次,数字 1 出现了 1 次,那么密码可能是 "01" 或者 "10" 。由于密码可能会重置,因此小红每次尝试的成功概率为 12 \frac{1}{2} 21​ 。

尝试次数的期望为 12+2∗14+3∗18+4∗116...=2 \frac{1}{2} + 2 * \frac{1}{4} + 3 * \frac{1}{8} + 4 * \frac{1}{16} ... = 2 21​+2∗41​+3∗81​+4∗161​...=2

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const ll mo = 1e9 + 7;
const int N = 1e7 + 1;
ll a[11];
ll f[N],inv[N];
ll qpow(ll a, ll b)
{
	ll ans = 1;
	while (b > 0)
	{
		if (b & 1)
			ans = ans * a % mo;
		a = a * a % mo;
		b >>= 1;
	}
	return ans;
}
int main()
{
	int sum=0;
	for (int i = 0; i <= 9; i++)
	{
		cin >> a[i];
		sum += a[i];
	}
	f[0] = 1;
	for (int i = 1; i <= sum; ++i) f[i] = f[i - 1] * i % mo;
	inv[sum] = qpow(f[sum], mo - 2);
	for (int i = sum - 1; i > 0; --i) inv[i] = inv[i + 1] * (i + 1) % mo;
	ll ans =f[sum];
	for (int i = 0; i <= 9; i++)
	{
		if (a[i])
		{
			ans = ans * inv[a[i]] % mo;
		}
	}
	cout << ans;
}

 increment of coins

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

背包有三种硬币,AAA 枚金币,BBB 枚银币, CCC 枚铜币。
在某一种硬币有100枚,之前重复以下操作:
随机从背包选一枚硬币。(每一个硬币被取到的概率相等。)然后放一枚一样的硬币进去。
请计算操作次数的期望值。

输入描述:

输入三个整数A,B,C。

数据范围:

0≤A,B,C≤990 \le A,B,C \le 990≤A,B,C≤99

A+B+C≥1A+B+C \ge 1A+B+C≥1

输出描述:

请输出操作次数的期望值。你的输出与正确答案的误差应该最多10−610^{-6}10−6。

示例1

输入

复制99 99 99

输出

复制1.000000000

说明

在第一次操作,选择任何1枚硬币,背包里都是100枚硬币

 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
double dp[105][105][105];
int main()
{
    int a,b,c;
    cin>>a>>b>>c;
    for(int i=100;i>=0;i--)
    {
        for(int j=100;j>=0;j--)
        {
            for(int k=100;k>=0;k--)
            {
                if(i==100||j==100||k==100)dp[i][j][k]=0;
                else
                if(i+j+k!=0){
                    dp[i][j][k]+=(double)i/(i+j+k)*(dp[i+1][j][k]+1);
                    dp[i][j][k]+=(double)j/(i+j+k)*(dp[i][j+1][k]+1);
                    dp[i][j][k]+=(double)k/(i+j+k)*(dp[i][j][k+1]+1);
                }
            }
        }
    }
    cout<<fixed<<setprecision(8)<<dp[a][b][c]<<endl;
}

 Little Pony and Expected Maximum

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

一个骰子有 mmm 面,第一个面有一个点,第二面有两个点,以此类推。Twilight Sparkle 确定投掷骰子时,每一面都是等概率出现的,即每面出现的概率为 1m\frac{1}{m}m1​。并且她知道每次投掷的结果是独立的。帮助她计算投掷 nnn 次骰子所能获得最大值的期望。

输入描述:

第一行包含两个整数 m,n(1≤m,n≤105)m,n(1\leq m,n\leq 10^5)m,n(1≤m,n≤105)。

输出描述:

输出一个实数表示期望最大值。当你的输出和答案的相对误差或者绝对误差不超过 10−410^{-4}10−4 时被视为正确。

示例1

输入

复制6 1

输出

复制3.500000000000

 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
//const ll mo = 1e9 + 7;
const int N = 1e7 + 1;
double f[N];
double qpow(double a, ll b)
{
	double ans = 1.0;
	while (b > 0)
	{
		if (b & 1)
			ans = ans * a;
		a = a * a;
		b >>= 1;
	}
	return ans;
}
int main()
{
	int m, n;
	cin >> m >> n;
	double ans = 0;
	for (int i = 1; i <= m; i++)
	{
		f[i] = qpow((double)i / m, n);
	}

	for (int i = 1; i <= m; i++)
	{
		ans += (double)i * (f[i] - f[i - 1]);
	}
	cout << ans;
}

Messages

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网

题目描述

Monocarp 是 nnn 个学生的导师,他通过发送消息和学生练习。现在有很多条消息,Monocarp 希望第 iii 个学生能够阅读编号为 mim_imi​ 的消息。但是学生只会阅读置顶的消息,因此他需要把一些消息置顶。
学生 iii 有一个属性 kik_iki​。如果 Monocarp 置顶了 ttt 条消息,若 t≤kit\le k_it≤ki​,该学生会阅读所有置顶消息;否则,该学生会从置顶的 ttt 条消息中随机选 kik_iki​ 条阅读。
你需要求出在使得第 iii 名学生阅读到编号为 mim_imi​ 的消息的 iii 的数量的期望值最大时,Monocarp 应该置顶哪些消息。如果有多个答案,输出任意一种。

输入描述:

第一行一个整数 n (1≤n≤2×105)n\ (1\le n\le 2\times 10^5)n (1≤n≤2×105)。
接下来 nnn 行,第 iii 行有两个整数 mi,ki (1≤mi≤2×105,1≤ki≤20)m_i,k_i\ (1\le m_i\le 2\times 10^5,1\le k_i\le 20)mi​,ki​ (1≤mi​≤2×105,1≤ki​≤20)。

输出描述:

第一行一个整数 t(1≤t≤2⋅105)t(1\leq t\leq 2\cdot10^5)t(1≤t≤2⋅105),表示你置顶的消息条数。

第二行包含 ttt 个不同的整数 c1,c2,…,ct(1≤ci≤2⋅105)c_1,c_2,\dots,c_t (1\leq c_i\leq 2\cdot10^5)c1​,c2​,…,ct​(1≤ci​≤2⋅105),表示你置顶的消息编号。

示例1

输入

3
10 1
10 2
5 2

输出

2

5 10

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
//const ll mo = 1e9 + 7;
const int N = 2e5 + 5;
int m[N], k[N];

bool check(pair<int, int> a, pair<int, int> b)
{
	return a.first * b.second > a.second * b.first;
}
int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> m[i] >> k[i];
	}
	vector<int>cert;
	pair<int, int >ans = {0, 1};
	for (int i = 1; i <= 20; i++)
	{
		vector<int> s(N);
		for (int j = 0; j < n; j++)
		{
			s[m[j]] += min(i, k[j]);
		}
		
		vector<pair<int, int>>a;
		for (int j = 0; j < N; j++)
		{
			a.push_back(make_pair(s[j], j));
		}
		sort(a.rbegin(), a.rend());

		pair<int, int> cur_ans = {0, i};
		vector<int>cur_cert;

		for (int j = 0; j < i; j++)
		{
			cur_ans.first += a[j].first;
			cur_cert.push_back(a[j].second);
		}
		if (check(cur_ans, ans))
		{
			ans = cur_ans;
			cert = cur_cert;
		}
	}
	cout << cert.size() << endl;
	for (auto x : cert)
		cout << x << " ";
	cout << endl;
}
/*
x = 读到自己需要的消息的学生数量=x1+x2+x3+x4+...+xn
期望的可加性
Ez=Ex+Ey   (z=x+y)

Ex=Ex1+Ex2+Ex3+...+Exn

xi=1表示第i个学生读到mi

E[xi]=1*P(xi==1)+0*P(xi==0)= P(xi==1)第i个学生读到mi
而 P(xi==1)=|0    ,mi !∈{m1...mt}
			|1    ,mi∈{m1...mt} && t<=ki
			|ki/t ,t>ki

接下来要找一组 {m1...mt} , t  使得期望E[x]最大
*/

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值