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 ...
随机推荐
- 安装git之后,桌面出现蓝色问号的解决方法
安装了git之后,桌面的图标全部变成蓝色的问号. 把隐藏的文件全部显示,也没有在桌面找到.git的文件, 解决步骤: 1.把隐藏的文件全部显示: 工具-文件夹选项-查看在"隐藏文件和文件夹& ...
- 拖拽一个元素如此简单,mouse、drag、touch三兄弟的用处
最近需要做一个投票活动,上传图片时需要拖拽.缩放来裁剪图片,vue的组件不少,不过自己动手才能丰衣足食,一味使用别人的组件实在难以进步,所以自己研究一番. 一.mouse.drag.touch傻傻分不 ...
- 页面中嵌套iframe,微信浏览器长按二维码识别不了
问题:在微信浏览器内,页面中嵌套iframe,iframe中用户触发事件后有个弹框会显示二维码,用户长按二维码可以识别并跳转.尝试了一下,安卓是正常的,但是ios是识别不了的. 解决过程: 1.这里客 ...
- JavaDailyReports10_15
2020-10-15 16:12:16 今天学习了如何实现倒计时控制程序的运行: 1 package timer; 2 3 import java.util.Calendar; 4 import ja ...
- Java学习日报7.13
/** * *//** * @author 86152 * */package Employee;import java.util.Scanner;public class Employee{ pri ...
- Centos7上以RPM包方式安装Oracle 18c XE
Centos7上以RPM包方式安装Oracle 18c XE 安装阿里云 YUM 源 https://opsx.alibaba.com/mirror?lang=zh-CN 一.安装oracle数据库 ...
- Java中定时器Timer致命缺点(附学习方法)
简介 这篇文章我一直在纠结到底要不要写,不想写一来因为定时器用法比较简单,二来是面试中也不常问.后来还是决定写了主要是想把自己分析问题思路分享给大家,让大家在学习过程中能够参考,学习态度我相信大部分人 ...
- 010_MySQL
目录 初识MySQL 为什么学习数据库 什么是数据库 数据库分类 MySQL简介 Windows安装MySQL 安装建议 软件下载 安装步骤 安装SQLyog 下载安装 连接数据库 简单操作 命令行连 ...
- Docusaurus2 快速建站,发布 GitHub Pages
Docusaurus2 可快速搭建文档.博客.官网等网站,并发布到 GitHub Pages, Serverless 等. 我们只需 Markdown 写写内容就行,也可直接编写 React 组件嵌入 ...
- ps 2020 下载
一款极具实用价值的作图软件--ps,由于正版价格昂贵,所以这里分享破解版的资源.b话少说,下面是下载链接和安装步骤: 下载链接: 百度网盘链接:https://pan.baidu.com/s/1XPf ...