2017 ICPC Asia Urumqi A.coins (概率DP + 期望)
题目链接:Coins
Description
Alice and Bob are playing a simple game. They line up a row of nn identical coins, all with the heads facing down onto the table and the tails upward.
For exactly mm times they select any kk of the coins and toss them into the air, replacing each of them either heads-up or heads-down with the same possibility. Their purpose is to gain as many coins heads-up as they can.
Input
The input has several test cases and the first line contains the integer \(t (1 \le t \le 1000)\) which is the total number of cases.
For each case, a line contains three space-separated integers \(n\), \(m (1 \le n, m \le 100)\) and \(k (1 \le k \le n)\).
Output
For each test case, output the expected number of coins heads-up which you could have at the end under the optimal strategy, as a real number with the precision of \(3\) digits.
Sample input
6
2 1 1
2 3 1
5 4 3
6 2 3
6 100 1
6 100 2
Sample output
0.500
1.250
3.479
3.000
5.500
5.000
Solution
题意
桌上放置着 \(n\) 个反面朝上的硬币,有 \(m\) 此操作,每次选择任意 \(k\) 个硬币抛向空中,每个硬币落到桌子后正面朝上和反面朝上的概率相同,求最终正面朝上的硬币的期望。
题解
概率DP 期望
期望 = 概率 * 总数
\(f(i, j)\) 表示为抛 \(i\) 枚硬币 \(j\) 枚硬币朝上的概率。则有 \(f(i, j)= 0.5 * f(i - 1, j) + 0.5 * f(i - 1, j - 1)\),其中 \(f(i, 0) = 2 ^ i\)。
\(DP(i, j)\) 表示第 \(i\) 次操作后有 \(j\) 枚正面朝上的硬币的概率,则反面硬币的个数为 \(n - j\)。
如果 \(n - j >= k\),那么只要在反面朝上的硬币中选择 \(k\) 枚抛即可。抛完 \(k\) 枚硬币后有 \(0 \sim k\) 枚硬币可能会正面朝上,递推方程为 \(DP(i + 1, j + l) = \sum_{l = 0}^{k} DP(i, j) * f(k, l)\)。
如果 \(n - j < k\),那么除了要抛 \(n - j\) 枚反面朝上的硬币,还要选择 \(k - (n - j)\) 枚正面朝上的硬币,这样最后正面朝上的个数是本来正面就朝上的 \(j-(k-(n-j))\) 枚加上抛了之后朝上的 \(l\ (0\le l\le k)\) 枚,递推方程为 \(DP(i + 1, j - (k - (n - j)) + l) = \sum_{l = 0}^{k} DP(i, j) * f(k, l)\)。
Code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
double dp[maxn][maxn];
double f[maxn][maxn];
int n, k, m;
void init() {
f[0][0] = 1;
for (int i = 1; i <= 100; ++i) {
f[i][0] = pow(0.5, i);
for (int j = 1; j <= 100; ++j) {
f[i][j] = (f[i - 1][j] + f[i - 1][j - 1]) / 2.0;
}
}
}
int main() {
init();
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d%d", &n, &m, &k);
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for (int i = 0; i < m; ++i) {
for (int j = 0; j <= n; ++j) {
for (int l = 0; l <= k; ++l) {
if (n - j >= k) {
dp[i + 1][j + l] += dp[i][j] * f[k][l];
} else {
dp[i + 1][j + l - (k - (n - j))] += dp[i][j] * f[k][l];
}
}
}
}
double ans = 0;
for (int i = 1; i <= n; ++i) {
ans += 1.0 * i * dp[m][i];
}
printf("%.3f\n", ans);
}
return 0;
}
2017 ICPC Asia Urumqi A.coins (概率DP + 期望)的更多相关文章
- luogu P6835 概率DP 期望
luogu P6835 概率DP 期望 洛谷 P6835 原题链接 题意 n + 1个节点,第i个节点都有指向i + 1的一条单向路,现在给他们添加m条边,每条边都从一个节点指向小于等于自己的一个节点 ...
- 2017 ICPC乌鲁木齐 A Coins 概率dp
Coins 题意:一开始所有n个硬币都是反面朝上的,每次必须拿k个来抛,抛的人足够聪明,问m次之后向上的硬币的期望. 首先说了这个足够聪明的意思,就是只要向反面的有k个就不会sb地去拿向正面的来抛,想 ...
- ACM-ICPC 2017 Asia Urumqi A. Coins
Alice and Bob are playing a simple game. They line up a row of n identical coins, all with the heads ...
- atcoderI - Coins ( 概率DP)
I - Coins Time Limit: 2 sec / Memory Limit: 1024 MB Score : 100100 points Problem Statement Let NN b ...
- HDU5985 Lucky Coins 概率dp
题意:给你N种硬币,每种硬币有Si个,有Pi 概率朝上,每次抛所有硬币抛起,所有反面的拿掉,问每种硬币成为最后的lucky硬币的概率. 题解:都知道是概率dp,但是模拟赛时思路非常模糊,很纠结,dp[ ...
- Gym 101606F - Flipping Coins - [概率DP]
题目链接:https://codeforc.es/gym/101606/problem/F 题解: 假设 $f[i][j]$ 表示抛 $i$ 次硬币,有 $j$ 个硬币正面朝上的概率. 所以只有两种挑 ...
- 概率dp+期望dp 题目列表(一)
表示对概率和期望还不是很清楚定义. 目前暂时只知道概率正推,期望逆推,然后概率*某个数值=期望. 为什么期望是逆推的,例如你求到某一个点的概率我们可以求得,然后我们只要运用dp从1~n每次都加下去就好 ...
- ACM-ICPC 2017 Asia Urumqi A. Coins【期望dp】
题目链接:https://www.jisuanke.com/contest/2870?view=challenges 题目大意:给出n个都正面朝下的硬币,操作m次,每次都选取k枚硬币抛到空中,求操作m ...
- HDU.5985.Lucky Coins(概率DP)
题目链接 \(Description\) 有n(n<=10)种硬币,已知每种硬币的数量和它抛一次正面朝上的概率pi.进行如下过程:每次抛一次所有硬币,将正面朝下的硬币去掉.重复该过程直到只剩一种 ...
随机推荐
- datetime timestamp使用
#coding=utf-8 import time import datetime def yes_time(): #获取当前时间 now_time = datetime.datetime.now() ...
- js 中 !!的用法
!!是将表达式强制转化为bool值的运算,运算结果为true或false,表达式是什么值,结果就是对应的bool值,不再取非. 不是取非再取非的意思!!! !!false=false; 要注意f ...
- 43-python基础-python3-字符串-常用字符串方法(一)-upper()-lower()-isupper()-islower()
请注意, 这些方法没有改变字符串本身,而是返回一个新字符串. 如果你希望改变原来的字符串,就必须在该字符串上调用 upper()或 lower(),然后将这个新字符串赋给保存原来字符串的变量. 1 ...
- Java-技术专区-技术栈分析辨证方法
1.好多公司动不动就JVM.高并发.分布式.微服务等等,我没有实际经验. 2.从事Java开发三年了,目前的职位是高级Java工程师,感觉技术和工资都到了瓶颈,对以后的发展方向有些迷茫. 3.加班时间 ...
- java final关键字详解
final是java中保留关键字,可以声明成员变量.类.方法与本地变量,一旦引用final关键字,将不能再改变这个引用,编译器会检查代码,要是想改变该引用,会报错. final变量? 凡是对成员变量或 ...
- linux 下新建文件自动加锁的解决办法
导致文件夹里面无法保存别的文件 sudo chmod 777 -R 文件或目录
- jsp struts2导入excel并且存储到数据库中
开发中遇到一个问题: 需要从外部导入excel,拿到其中的数据然后保存到数据库中. 1.先在jsp端使用input进行上传: <form action="storeOBDexcel&q ...
- 【牛客网-剑指offer】旋转数组的最小数字
题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋 ...
- Ubuntu16.04+cuda9.0安装教程
1.安装NVIDIA驱动 首先去官网(http://www.nvidia.cn/Download/index.aspx?lang=cn)查找适配自己电脑GPU的驱动,我的电脑驱动版本如下: 执行如下语 ...
- 总结下awk基本用法
命令格式: awk '{commands} [{other commands}]' awk 'condition{commands} [{other commands}]' 如:awk '$4==&q ...