「ZJOI2019」麻将
传送门
Solution
对于条件一:记录一个\(cnt\)表示牌个数\(≥2\)的个数
设\(dp_{i,0/1,j,k}\)表示考虑了\(1...i\),当前是否有对子,以\(i-1\),\(i\)开始的顺子数为\(j\),\(k\)个,的最大面子数
其中\(dp_i\)是一个大小为\(18\)的状态,我们通过搜索可以发现这样的状态很少
不胡的状态有\(2091\)个,可以直接开一个\(map\)来记录,这里要记得重载小于号
将期望看成,如果摸了\(i(i≥13)\)张牌,如果仍然不胡则贡献\(1\)
答案需要求出有\(i\)张牌时仍然不胡的方案数,并乘一个排列数\((4n-i)!\)
仍然考虑dp,设\(f_{i,j,k}\)表示考虑\(1...i\),当前状态为\(j\),一共选了\(k\)张牌的方案数
转移时枚举\(i+1\)面值选多少张即可
总复杂度\(O(n^2S)\),\(S\)表示状态数
Code
#include<bits/stdc++.h>
using namespace std;
#define reg register
inline int read()
{int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}return x*f;
}
const int P=998244353,C[5][5]={{1},{1,1},{1,2,1},{1,3,3,1},{1,4,6,4,1}};
int Mul(int x,int y){return (1ll*x*y)%P;}
int Add(int x,int y){return (x+y)%P;}
int n,w[15],t[105];
void rw(int &x,int y){if(min(y,4)>x)x=y;}
struct State
{int f[18],cnt;State(){memset(f,-1,sizeof f);f[0]=cnt=0;}bool operator <(const State&o)const{if(cnt!=o.cnt) return (cnt<o.cnt);for(int i=0;i<18;++i)if(f[i]!=o.f[i]) return (f[i]<o.f[i]);return false;}bool HU(){return cnt>=7||f[9]>=4;}friend State Trans(State a,int b){register int i,j,k;State c;c.cnt=a.cnt+(b>=2);for(i=0;i<3;++i)for(j=0;j<3;++j)for(k=0;k<3&&i+j+k<=b;++k){if(~a.f[i*3+j]) rw(c.f[j*3+k],a.f[i*3+j]+i+(b-i-j-k)/3);if(~a.f[i*3+j+9])rw(c.f[9+j*3+k],a.f[9+i*3+j]+i+(b-i-j-k)/3);if(i+j+k+2<=b&&~a.f[i*3+j]) rw(c.f[9+j*3+k],a.f[i*3+j]+i);}return c;}
}st[2100];int tot;int tr[2100][5];
std::map<State,int> mp;
int dfs(State cur)
{if(cur.HU()) return 0;if(mp.find(cur)!=mp.end()) return mp[cur];st[mp[cur]=++tot]=cur;int now=tot;for(int i=0;i<=4;++i) tr[now][i]=dfs(Trans(cur,i));return now;
}
int f[2][2100][405],fac[450],inv[450],ans;
int main()
{dfs(State());register int sum,i,j,k,l;for(inv[0]=inv[1]=fac[0]=fac[1]=1,i=2;i<=420;++i)fac[i]=Mul(fac[i-1],i),inv[i]=Mul((P-P/i),inv[P%i]);for(i=2;i<=420;++i) inv[i]=Mul(inv[i],inv[i-1]);n=read();for(i=1;i<=13;++i) w[i]=read(),read(),++t[w[i]];f[0][1][0]=1;for(sum=0,i=1;i<=n;sum+=t[i],++i){memset(f[i&1],0,sizeof f[i&1]);for(j=1;j<=tot;++j)for(k=sum;k<=(i-1)<<2;++k)if(f[(i&1)^1][j][k])for(l=t[i];l<=4;++l)if(tr[j][l]){int nxt=tr[j][l];f[i&1][nxt][k+l]=Add(f[i&1][nxt][k+l],Mul(f[(i&1)^1][j][k],Mul(C[4-t[i]][l-t[i]],Mul(inv[k-sum],fac[k+l-sum-t[i]]))));}}ans=0;for(i=0;i<=(n<<2);ans=Add(ans,Mul(l,fac[(n<<2)-i])),++i)for(l=0,j=1;j<=tot;l=Add(l,f[n&1][j][i]),++j);printf("%d\n",Mul(ans,inv[(n<<2)-13]));return 0;
}
Blog来自PaperCloud,未经允许,请勿转载,TKS!
转载于:https://www.cnblogs.com/PaperCloud/p/11228285.html
「ZJOI2019」麻将相关推荐
- 【LOJ3047】「ZJOI2019」浙江省选
[题目链接] 点击打开链接 [思路要点] 对于 M = 1 M=1 M=1 的情况,问题即为求半平面交. 考虑 M M M 更大的情况,以 M = 2 M=2 M=2 为例. 首先去掉排名可以为第一的 ...
- 快手开源斗地主AI,入选ICML,能否干得过「冠军」柯洁?
来源:机器之心本文约4800字,建议阅读9分钟 AI打斗地主,除了信息不完全,还要学会合作与竞争. 众所周知,AI 在围棋上的实力是人类所不能及的.不过斗地主还不一定.在 2017 年 AlphaGo ...
- 地平线余凯:电动车,卖点不是车而是「智能」
汽车冠以「智能」,方可以称为颠覆式创新. <时代周刊>曾发表社评称,手机行业只分为两个阶段,iPhone 之前和 iPhone 之后.iPhone 横空出世之前,手机行业满世界充斥着数字键 ...
- AlphaGo Zero「无师自通」背后的伟大与局限 | 旷视孙剑解读
整理 | 安木 当你被 AlphaGo Zero 刷屏的时候,你是对人类的创造力产生自豪,还是对人类的未来感到担忧? 10 月 20 日,旷视科技(Face++)首席科学家孙剑博士接受了多家媒体的群访 ...
- 成都大运会「数智竞技邀请赛」启动,「开悟」平台为全球青年提供AI竞技舞台...
感谢阅读腾讯AI Lab微信号第138篇文章.本文将介绍腾讯AI Lab「开悟」平台为「世界大学生数智竞技邀请赛」提供技术支持,向全球大学生提供AI竞技舞台. 3月18日,在第31届世界大学生夏季运动 ...
- 如何直观地理解「协方差矩阵」?
如何直观地理解「协方差矩阵」? Xinyu Chen Urban Traffic Data Analytics 372 人赞同了该文章 协方差矩阵在统计学和机器学习中随处可见,一般而言,可视作方差和协 ...
- 消除左递归实验代码_「leetcode」108. 构造二叉搜索树【递归】【迭代】详解!
构造二叉搜索树,一不小心就平衡了 ❞ 108.将有序数组转换为二叉搜索树 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树 ...
- 不带头节点的链表有哪些缺点_23张图!万字详解「链表」,从小白到大佬!
链表和数组是数据类型中两个重要又常用的基础数据类型. 数组是连续存储在内存中的数据结构,因此它的优势是可以通过下标迅速的找到元素的位置,而它的缺点则是在插入和删除元素时会导致大量元素的被迫移动,为了解 ...
- 一位老码农的分享:一线程序员该如何面对「中年危机」?
如果这是第二次看到我的文章,欢迎文末扫码订阅我个人的公众号(跨界架构师)哟~ 本文长度为2728字,建议阅读8分钟. 坚持原创,每一篇都是用心之作- 先来聊一下这个问题的背景吧. 前两天有小伙伴问 ...
- 机器人 Ameca「苏醒」瞬间逼真到令人恐惧,网友纷纷惊叹……
整理 | 禾木木 出品 | AI科技大本营(ID:rgznai100) 近日,国内外网友都被一段机器人「苏醒」的视频惊讶到. 视频开始时,机器人似乎已经睡着,眼睛闭着,头部略微向下倾斜.随着肩膀的伸展 ...
最新文章
- 生物信息学 生物科学、农学、林学、医学
- Hyper-V Server 2008 R2 加入活动目录的方法
- 比尔盖茨,马斯克、霍金都告诉你:为什么要警惕人工智能(中)
- Webshell免杀绕过waf
- 静态创意和动态创意_我在22岁时学到的关于创意指导的知识
- 创建ftp服务器后html,搭建ftp服务器需要用到固定IP吗
- linux 查看触摸屏信息,英创信息技术eGalax触摸屏在Linux/X11下的标定方法
- 错误: 无法生成项目输出组“内容文件来自WebApplication1(活动)”
- python接口封装_Python 接口测试之接口关键字封装
- mysql与mimic安装_MIMICIII 数据库教程(4)——MIMIC数据库的安装 #丁香打卡#
- qt调用import sys库_【开源库】使用Qt.py进行开发
- readelf命令使用说明
- 数据抽取的常见理论方法
- jmeter录制postman脚本
- 数据可视化--实验四:地理数据可视化
- 如何将计算机的硬盘分割,电脑硬盘如何快速分区
- 一名大学生选择军哥的乾颐堂是如何顺利通过华为HCIE的,又如何应对HCIE面试呢?...
- DNA计算 与 肽展公式 推导 AOPM-A 变胸腺苷, AOPM-O尿胞变腺苷, AOPM-P尿胞变鸟苷, AOPM-M鸟腺苷的 S形螺旋纹 血氧峰 触发器分子式 严谨完整过程
- python sns画布大小设置
- linux+gunzip解压命令,Linux gunzip命令解析 gunzip解压文件的方法
热门文章
- 「leetcode」本周小结!(回溯算法系列一)
- 如何在 Mac 上重命名 Apple Magic Mouse?
- Posterino for Mac(图片拼贴编辑器)
- Millumin for Mac视频实时编辑软件
- Lock and Load FCPX 报错处理方法
- 如何在iPhone或Mac上自定义共享菜单?
- 聊聊flink的KvStateRegistryGateway
- 拇指接龙游戏从WIN32向Android移植过程问题记录(1)
- AI加持,计算机要拥有嗅觉了;GPU终于可用于Google Compute Engine | AI开发者头条
- Flex tree加三状态的Checkbox