P1837 单人纸牌
写在前面
- 感谢巨佬 yu__xuan 的帮助!
- 原本题解区的大佬们大都写的九层循环,其实此题如果写成状压,可以将这九层循环写成一层,非但简洁、代码可读性强,常数也比直接九维 dp 小。
算法思路
由于每一行都只有四张牌,考虑写成五进制状压 dp。
设当前状态为 \(t\),则五进制状压 dp 取出第 \(i\) 行的状态的方式:\(\frac{t}{5^i}\!\!\!\!\mod 5\)(视初始行为第 \(0\) 行)
因此,若设第 \(i\) 行的第 \(j\) 张牌的点数为 \(a_{i,j}\),则状态转移方程为:
\]
其中 \(p\) 为此次转移的概率,等于从状态 \(t\) 能转移到的状态数总和的倒数。
边界条件: \(f_{5^9 - 1} = 1\)。
倒序枚举所有状态,每当找到一个当前答案不为 \(0\) 的状态时,先统计出它能更新到的状态数,算出转移的概率 \(P\),然后用该状态去更新它所能更新到的状态的答案。
由于一直在拿牌,表示状态的变量会逐渐减小,倒序枚举状态时可行的。
Tips
读入的时候用类似于快速读入的方式过滤一下不合法字符可以极大地简化读入部分的代码。
扑克牌的点数不等同于真实的扑克牌的点数,因此统计的时候不需要再对点数进行处理,直接将
char转成int存下来即可。
Code
#include<bits/stdc++.h>
#define LF double
const int pow5[] = {1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125};
using namespace std;
LF f[1953125];
int a[10][5];
char Getch() {char ch = getchar(); while((!isalpha(ch)) && (!isdigit(ch))) ch = getchar(); return ch;}
int main() {
for(register int i = 0; i < 9; ++i) {
for(register int j = 1; j <= 4; ++j) {
a[i][j] = Getch(); Getch();
}
}
f[1953124] = 1.0;
for(register int t = pow5[9] - 1; t >= 0; --t) {
if(f[t] == 0) continue;
LF choise = 0;
for(register int p1 = 0; p1 < 9; ++p1) {
for(register int p2 = p1 + 1; p2 < 9; ++p2) {
if((a[p1][t / pow5[p1] % 5] == a[p2][t / pow5[p2] % 5]) && ((t / pow5[p1] % 5) > 0) && ((t / pow5[p2] % 5) > 0)) choise++;
}
}
LF P = f[t] * 1.0 / choise;
for(register int p1 = 0; p1 < 9; ++p1) {
for(register int p2 = p1 + 1; p2 < 9; ++p2) {
if((a[p1][t / pow5[p1] % 5] == a[p2][t / pow5[p2] % 5]) && ((t / pow5[p1] % 5) > 0) && ((t / pow5[p2] % 5) > 0)) {
f[t - pow5[p1] - pow5[p2]] += P;
}
}
}
}
printf("%lf", f[0]);
return 0;
}
P1837 单人纸牌的更多相关文章
- P1837 单人纸牌_NOI导刊2011提高(04)
题目描述 单人纸牌游戏,共36张牌分成9叠,每叠4张牌面向上.每次,游戏者可以从某两个不同的牌堆最顶上取出两张牌面相同的牌(如黑桃10和梅花10)并且一起拿走.如果最后所有纸牌都被取走,则游戏者就赢了 ...
- 单人纸牌_NOI导刊2011提高(04)
单人纸牌 时间限制: 1 Sec 内存限制: 128 MB 题目描述 单人纸牌游戏,共 36 张牌分成 9 叠,每叠 4 张牌面向上.每次,游戏者可以从某两个不同的牌堆最顶上取出两张牌面相同的牌(如 ...
- linux快捷键及主要命令(转载)
作者:幻影快递Linux小组 翻译 2004-10-05 22:03:01 来自:Linux新手管理员指南(中文版) 5.1 Linux基本的键盘输入快捷键和一些常用命令 5.2 帮助命令 5.3 系 ...
- code vs 1098 均分纸牌(贪心)
1098 均分纸牌 2002年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 有 N 堆纸牌 ...
- C语言-纸牌计算24点小游戏
C语言实现纸牌计算24点小游戏 利用系统时间设定随机种子生成4个随机数,并对4个数字之间的运算次序以及运算符号进行枚举,从而计算判断是否能得出24,以达到程序目的.程序主要功能已完成,目前还有部分细节 ...
- 一起来做webgame,《Javascript蜘蛛纸牌》
不得不说,做游戏是会上瘾的,这次带来的是win系统上的经典游戏<蜘蛛纸牌>,不能完美,但求一玩 移牌 0 次 Javascript game_蜘蛛纸牌 正在努力加载... // " ...
- 洛谷 P1031 均分纸牌 Label:续命模拟QAQ
题目描述 有 N 堆纸牌,编号分别为 1,2,…, N.每堆上有若干张,但纸牌总数必为 N 的倍数.可以在任一堆上取若于张纸牌,然后移动. 移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 ...
- 斯坦福iOS7公开课1-3笔记及纸牌Demo
1.MVC Model:模型 描述程序是什么,例如数据库操作之类的行文以及纸牌Demo里纸牌玩法都是写在Model这一层,通过Notification和KVO(后续文章会介绍)两种方式与Control ...
- [CareerCup] 8.1 Implement Blackjack 实现21点纸牌
8.1 Design the data structures for a generic deck of cards. Explain how you would subclass the data ...
随机推荐
- Cookie和登录注册
1. 什么是Cookie? 服务器通过 Set-Cookie 头给客户端一串字符串 客户端每次访问相同域名的网页时,必须带上这段字符串 客户端要在一段时间内保存这个Cookie Cookie 默认在用 ...
- 《中间件性能挑战赛--分布式统计和过滤的链路追踪》java 选手分享
2020年6月份天池举办的<中间件性能挑战赛>可谓是异常激烈,本人抽业余时间报名参与,感受比赛惨烈的同时,也有诸多感慨哈,总结一个多月的赛程,多少有一些心得与大家分享 本文原创地址:htt ...
- 死磕以太坊源码分析之MPT树-下
死磕以太坊源码分析之MPT树-下 文章以及资料请查看:https://github.com/blockchainGuide/ 上篇主要介绍了以太坊中的MPT树的原理,这篇主要会对MPT树涉及的源码进行 ...
- PHPExcel-Helper快速构建Excel
项目介绍 PHPExcel-Helper是什么? PHPExcel辅助开发类,帮助开发者快速创建各类excel. github PHPExcel-Helper存在的意义? 官方phpexcel库功能全 ...
- Spring源码深度解析之数据库连接JDBC
Spring源码深度解析之数据库连接JDBC JDBC(Java Data Base Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供 ...
- MP(MyBatis-Plus)的自动填充功能
什么是自动填充 有些表中会有更新时间.创建时间.更新人或者创建人这些字段. 每次对数据进行新增.删除.修改时都需要对这些字段进行设置.传统的做法是在进行这些操作前,对Entity的字段进行set设置, ...
- NOIP初赛篇——10计算机网络
网络的定义 所谓计算机网络,就是利用通信线路和设备,把分布在不同地理位置上的多台计算机连接起来. 计算机网络是现代通信技术与计算机奇数结合的产物. 网络中计算机与计算机之间的通信依靠协议进 ...
- 【MySQL 高级】知识拓展
MySQL高级 知识拓展 MySQL高级 知识拓展 数据量 和 B+树 的关系 事务隔离级别集底层原理MVCC 唯一索引和普通索引的关键不同点 MRR:multi range read 练习和总结
- 支持向量机(SVM)原理详解
SVM简介 支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机:SVM还包括核技巧, ...
- Docker学习笔记之向服务器部署应用程序
部署的应用仅仅是简单应用程序,使用的是node管理的web应用,具体我也不是很会,当然也可以配置tomcat服务器.这里主要是学习docker.需要客户机和服务机,其中服务机必须要为Linux操作系统 ...