2016级算法第五次上机-G.ModricWang的撒币游戏
1062 ModricWang的撒币游戏
思路
此题为2017年ACM-ICPC亚洲区域赛乌鲁木齐赛区的A题,现场94个队中有38个队做出此题。在这里作为满分以外的题,是为了让大家看一下外面一些题的风格,不要被三位助教的出题风格所局限。
此题首先需要知道一些高中数学概率论的知识。扔起N个硬币,如果每个硬币下落时,正反面朝上的概率都是确定的,那么这些硬币中正面朝上的数量是呈二项分布的。
考虑使用DP,\(prob[i][j]\) 表示扔了第i次后,有j个硬币正面朝上的概率。首先根据题设,\(prob[0][0]=1\),每次根据\(i\)这一行来推出\(i+1\)这一行,扔硬币的过程会让\(prob[i][j]\) 以二项分布分散到\(prob[i+1][p]和prob[i+1][p+k]\) 这\(k+1\) 项里。j、p和n的关系如下:\(p \leq j \leq p+k \leq n\) ,意义为:j表示当前有多少个硬币向上,p表示下一步最少有多少个硬币向上,(p+k)表示下一步最多有多少个硬币向上。所谓的最优策略就是,让p尽量的大,也就是扔硬币的时候尽量选朝下的扔。最终答案就是 \(\Sigma_{i=1}^{n} i*prob[m][i]\)。
具体进行操作时可以有一些优化策略,例如
- 使用滚动数组来节省空间
- 忽略概率小于\(1e-3\) 的项
但是我做的时候没有采取这些策略,因为
- 根据计算,内存空间是足够的
- 虽然\(O(Tnmk)\) 在此题中达到了\(1e9\)的数量级,但是计算过程中的核心语句是\(a+=b*c\) 的形式,这样的语句在X86架构下就是一条FMA指令的事,不必担心常数的问题。 reference: 乘积累加运算 - 维基百科
and FMA指令集 - 维基百科
时间复杂度:\(O(Tnmk)\),空间复杂度\(O(nm)\)
代码:
#include <iostream>
#include <iomanip>
#include <cstring>
using std::ios_base;
using std::cin;
using std::cout;
using std::min;
using std::fixed;
using std::setprecision;
const int MaxNum = 100 + 7;
double prob[MaxNum][MaxNum];
double binomial_distribution[MaxNum][MaxNum];
//计算二项分布的概率值
void get_binomial_distribution() {
double prob_sum = 1;
for (int i = 1; i < MaxNum; i++) {
double C = 1;
prob_sum *= 2;
binomial_distribution[i][0] = C/prob_sum;
for (int j = 1; j <= i; j++) {
C = C*(i - j + 1)/j;
binomial_distribution[i][j] = C/prob_sum;
}
}
}
int main() {
#ifdef ONLINE_JUDGE
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
#else
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
get_binomial_distribution();
int T;
while (cin >> T) {
while (T--) {
int n, m, k;
cin >> n >> m >> k;
memset(prob, 0, sizeof(prob));
prob[0][0] = 1;
for (int step = 1; step <= m; step++) {
for (int i = 0; i <= n; i++) {
int begin_pos = min(i, n - k); //这就是思路里写的p
for (int j = 0; j <= k; j++) {
prob[step][begin_pos + j] += prob[step - 1][i]*binomial_distribution[k][j]; //DP过程
}
}
}
double ans = 0;
for (int i = 1; i <= n; i++) {
ans += i*prob[m][i];
}
cout << fixed << setprecision(3) << ans << "\n";
}
}
}
2016级算法第五次上机-G.ModricWang的撒币游戏的更多相关文章
- 2016级算法第五次上机-F.ModricWang的水系法术
1066 ModricWang的水系法术 思路 比较典型的最大流问题,需要注意的是,题目已经暗示(明示)了这里的边是双向的,在建图的时候需要加上反向边的容量值. 解决最大流问题的基本思路就是不断在残量 ...
- 2016级算法第六次上机-G.ModricWang likes geometry
1116 ModricWang likes geometry 思路 难题,非常考察几何知识,放在这里作为计算几何场次的最难的题. 原题地址 原版题解 代码
- 2016级算法第四次上机-G.ModricWang的序列问题 II
1021 ModricWang的序列问题II 思路 此题与上一题区别不是很大,只是增加了一个长度限制,当场通过的人数就少了很多. 大体解题过程与上一题相同.区别在于对\(f[]\) 的操作.没有长度限 ...
- 2016级算法第五次上机-E.AlvinZH的学霸养成记IV
1039 AlvinZH的学霸养成记IV 思路 难题,最大二分图匹配. 难点在于如何转化问题,n对n,一个只能攻击一个,判断是否存在一种攻击方案我方不死团灭对方.可以想到把所有随从看作点,对于可攻击的 ...
- 2016级算法第五次上机-C.Bamboo和"Coco"
1064 Bamboo和"Coco" 分析题意 每个亡灵至少一个花瓣,相邻的亡灵中思念值高的要获得的花瓣高(思念值相等是不需要花瓣一样多的).主要考贪心思路,为了使得花瓣总量最少, ...
- 2016级算法第五次上机-B.Bamboo&APTX4844魔发药水
Bamboo&APTX4844魔发药水 题意 "于是,Bamboo耐着性子,看巫师从袖子里掏出 M 瓶时光泉水和 K 粒绿色能量.每瓶时光泉水重量为 c ,生发效果为 l:每粒绿色能 ...
- 2016级算法第三次上机-G.Winter is coming
904 Winter is coming 思路 难题.首先简化问题, \(n\) 个0与 \(m\) 个1排成一列,连续的0不能超过x个,连续的1不能超过y个,求排列方法数. 显然会想到这是动态规划. ...
- 2016级算法第五次上机-A.Beihang Collegiate Pronunciation Contest 2017
1065 Beihang Collegiate Pronunciation Contest 2017 思路 在字符串中不断做匹配 找到一个匹配就输出 时间复杂度\(O(n)\) ps.模式串是定长的, ...
- 2016级算法第五次上机-D.AlvinZH的学霸养成记III
850 AlvinZH的学霸养成记III 思路 难题.概率DP. 第一种思考方式:直接DP dp[i]:从已经有i个学霸到所有人变成学霸的期望. 那么答案为dp[1],需要从后往前逆推.对于某一天,有 ...
随机推荐
- linux系统文件的安全与特殊权限
一. 文件与目录的原始属性 由于不希望文件具有可执行的原始权限,默认情况下,文件是没有可执行(x)权限的,因此文件的原始属性是:-rw-rw-rw(0666) 目录的原始属性全部开放,为:-rwxrw ...
- Hibernate入门级实例
一.开发环境 Win8 + jdk1.7 + MyEclipse + Tomcat5.0 + MySQL 说明:其实Hibernate是非常独立的框架,根本不需要MyEclipse,Eclipse,T ...
- Springboot-读取核心配置文件及自定义配置文件
读取核心配置文件 核心配置文件是指在resources根目录下的application.properties或application.yml配置文件,读取这两个配置文件的方法有两种,都比较简单. 核心 ...
- mysql varchar 类型 超出字符
4.0版本以下,varchar(50),指的是50字节,如果存放UTF8汉字时,只能存16个(每个汉字3字节) 5.0版本以上,varchar(50),指的是50字符,无论存放的是数字.字母还是UTF ...
- 随机抽样问题(蓄水池问题Reservoir Sampling)
转自:孤影醉残阳 http://hi.baidu.com/siyupy/item/e4bb218fedf4a0864414cfad 随机抽样问题(蓄水池问题Reservoir Sampling) 随即 ...
- 1056 IMMEDIATE DECODABILITY
题目链接: http://poj.org/problem?id=1056 题意: 给定编码集, 判断它是否为可解码(没有任何一个编码是其他编码的前缀). 分析: 简单题目, 遍历一遍即可, 只需判断两 ...
- 前端实用软件: Markdown工具之---Typora实用技巧(总结)
Typora是一款超简洁的markdown编辑器,具有如下特点: 完全免费,目前已支持中文 跨平台,支持windows,mac,linux 支持数学公式输入,图片插入 极其简洁,无多余功能 界面所见即 ...
- opencv——(动态)旋转图像
#include "stdafx.h" #include <opencv2\opencv.hpp> #include <opencv\cv.h> #incl ...
- Android-bindService远程服务(Aidl)-初步
之前上一篇讲解到本地服务,本地服务只能在自身APP中Activity访问Service,调用Service里面到方法等操作 如果想A应用访问B应用里面的方法,属于跨进程调用,如果Android不特供这 ...
- duilib入门简明教程 -- 完整的自绘标题栏(8)
看了前面那么多教程,相信对duilib已有基本映像了,我们就快马加鞭,做出一个完整的自绘标题栏吧~ 看到下面这个效果图,小伙伴们是不是有点惊呆了呢~O(∩_∩)O~ duil ...