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],需要从后往前逆推.对于某一天,有 ...
随机推荐
- jQuery autocomplete -默认
<!doctype html> <html> <head> <meta name="content-type" content=" ...
- 20-list简单使用:
C++list的使用总结及常用list操作 C++中list用法详解 STL中list的erase()方法的使用 listiterator 最近刚刚接触stl的list 学习的时候遇到了很多 ...
- 富文本编辑器和fastdfs的使用
宜立方商城的系统架构a) 功能介绍(项目架构,有哪些功能模块,这些功能模块如何实现?)b) 架构讲解工程搭建-后台工程c) 使用maven搭建工程(后台工程如何搭建?)d) 使用maven的tomca ...
- SpringBoot 中 使用Mybatis时 如果后端数据库为 Oracle注意事项
报错信息如下: Could not set parameters for mapping: ParameterMapping{property='age', mode=IN, javaType=cla ...
- 1028 Web Navigation
题目链接: http://poj.org/problem?id=1028 题意: 模拟浏览器的前进/后退/访问/退出 的四个操作. 输出当前访问的URL或者Ignore(如果不能前进/后退). 分析: ...
- 01 A Counting DNA Nucleotides
Problem A string is simply an ordered collection of symbols selected from some alphabet and formed i ...
- ceph常用指令
一.集群 1.启动一个ceph 进程 启动mon进程 service ceph start mon.node1 启动msd进程 service ceph start mds.node1 启动osd进 ...
- jQuary总结1:jQuary的优点和地位
1 什么是jQuery? jQuery是一个快速,小巧,功能丰富的JavaScript库. javascript库: 就是存放javascript代码的仓库 jQuery作为一个迭代多年的优秀框架,是 ...
- UVa 1220 Party at Hali-Bula (树形DP,最大独立集)
题意:公司有 n 个人形成一个树形结构,除了老板都有唯一的一个直系上司,要求选尽量多的人,但不能同时选一人上和他的直系上司,问最多能选多少人,并且是不是唯一的方案. 析:这个题几乎就是树的最大的独立集 ...
- VC6.0加载lib文件的三种方法
MFC编写程序,都要用到动态链接库,MFC相关的动态库有MFCD42和MFC42等,MFC框架程序已经自动加载,那么如何引入第三方的动态链接库到工程中呢? 静态链接库是要先把程序中所需要使用的函数编译 ...