传送门

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」麻将相关推荐

  1. 【LOJ3047】「ZJOI2019」浙江省选

    [题目链接] 点击打开链接 [思路要点] 对于 M = 1 M=1 M=1 的情况,问题即为求半平面交. 考虑 M M M 更大的情况,以 M = 2 M=2 M=2 为例. 首先去掉排名可以为第一的 ...

  2. 快手开源斗地主AI,入选ICML,能否干得过「冠军」柯洁?

    来源:机器之心本文约4800字,建议阅读9分钟 AI打斗地主,除了信息不完全,还要学会合作与竞争. 众所周知,AI 在围棋上的实力是人类所不能及的.不过斗地主还不一定.在 2017 年 AlphaGo ...

  3. 地平线余凯:电动车,卖点不是车而是「智能」

    汽车冠以「智能」,方可以称为颠覆式创新. <时代周刊>曾发表社评称,手机行业只分为两个阶段,iPhone 之前和 iPhone 之后.iPhone 横空出世之前,手机行业满世界充斥着数字键 ...

  4. AlphaGo Zero「无师自通」背后的伟大与局限 | 旷视孙剑解读

    整理 | 安木 当你被 AlphaGo Zero 刷屏的时候,你是对人类的创造力产生自豪,还是对人类的未来感到担忧? 10 月 20 日,旷视科技(Face++)首席科学家孙剑博士接受了多家媒体的群访 ...

  5. 成都大运会「数智竞技邀请赛」启动,「开悟」平台为全球青年提供AI竞技舞台...

    感谢阅读腾讯AI Lab微信号第138篇文章.本文将介绍腾讯AI Lab「开悟」平台为「世界大学生数智竞技邀请赛」提供技术支持,向全球大学生提供AI竞技舞台. 3月18日,在第31届世界大学生夏季运动 ...

  6. 如何直观地理解「协方差矩阵」?

    如何直观地理解「协方差矩阵」? Xinyu Chen Urban Traffic Data Analytics 372 人赞同了该文章 协方差矩阵在统计学和机器学习中随处可见,一般而言,可视作方差和协 ...

  7. 消除左递归实验代码_「leetcode」108. 构造二叉搜索树【递归】【迭代】详解!

    构造二叉搜索树,一不小心就平衡了 ❞ 108.将有序数组转换为二叉搜索树 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树 ...

  8. 不带头节点的链表有哪些缺点_23张图!万字详解「链表」,从小白到大佬!

    链表和数组是数据类型中两个重要又常用的基础数据类型. 数组是连续存储在内存中的数据结构,因此它的优势是可以通过下标迅速的找到元素的位置,而它的缺点则是在插入和删除元素时会导致大量元素的被迫移动,为了解 ...

  9. 一位老码农的分享:一线程序员该如何面对「中年危机」?

    如果这是第二次看到我的文章,欢迎文末扫码订阅我个人的公众号(跨界架构师)哟~   本文长度为2728字,建议阅读8分钟. 坚持原创,每一篇都是用心之作- 先来聊一下这个问题的背景吧. 前两天有小伙伴问 ...

  10. 机器人 Ameca「苏醒」瞬间逼真到令人恐惧,网友纷纷惊叹……

    整理 | 禾木木 出品 | AI科技大本营(ID:rgznai100) 近日,国内外网友都被一段机器人「苏醒」的视频惊讶到. 视频开始时,机器人似乎已经睡着,眼睛闭着,头部略微向下倾斜.随着肩膀的伸展 ...

最新文章

  1. 生物信息学 生物科学、农学、林学、医学
  2. Hyper-V Server 2008 R2 加入活动目录的方法
  3. 比尔盖茨,马斯克、霍金都告诉你:为什么要警惕人工智能(中)
  4. Webshell免杀绕过waf
  5. 静态创意和动态创意_我在22岁时学到的关于创意指导的知识
  6. 创建ftp服务器后html,搭建ftp服务器需要用到固定IP吗
  7. linux 查看触摸屏信息,英创信息技术eGalax触摸屏在Linux/X11下的标定方法
  8. 错误: 无法生成项目输出组“内容文件来自WebApplication1(活动)”
  9. python接口封装_Python 接口测试之接口关键字封装
  10. mysql与mimic安装_MIMICIII 数据库教程(4)——MIMIC数据库的安装 #丁香打卡#
  11. qt调用import sys库_【开源库】使用Qt.py进行开发
  12. readelf命令使用说明
  13. 数据抽取的常见理论方法
  14. jmeter录制postman脚本
  15. 数据可视化--实验四:地理数据可视化
  16. 如何将计算机的硬盘分割,电脑硬盘如何快速分区
  17. 一名大学生选择军哥的乾颐堂是如何顺利通过华为HCIE的,又如何应对HCIE面试呢?...
  18. DNA计算 与 肽展公式 推导 AOPM-A 变胸腺苷, AOPM-O尿胞变腺苷, AOPM-P尿胞变鸟苷, AOPM-M鸟腺苷的 S形螺旋纹 血氧峰 触发器分子式 严谨完整过程
  19. python sns画布大小设置
  20. linux+gunzip解压命令,Linux gunzip命令解析 gunzip解压文件的方法

热门文章

  1. 「leetcode」本周小结!(回溯算法系列一)
  2. 如何在 Mac 上重命名 Apple Magic Mouse?
  3. Posterino for Mac(图片拼贴编辑器)
  4. Millumin for Mac视频实时编辑软件
  5. Lock and Load FCPX 报错处理方法
  6. 如何在iPhone或Mac上自定义共享菜单?
  7. 聊聊flink的KvStateRegistryGateway
  8. 拇指接龙游戏从WIN32向Android移植过程问题记录(1)
  9. AI加持,计算机要拥有嗅觉了;GPU终于可用于Google Compute Engine | AI开发者头条
  10. Flex tree加三状态的Checkbox