传送门

wdnm又是打麻将

首先国土无双可以直接枚举哪种牌用了\(2\)次算贡献,然后\(7\)个对子可以把每种牌的对子贡献排序,取最大的\(7\)个,剩下的牌直接暴力枚举是不行的,考虑dp,设\(f_{i,0\sim1,j,k,0\sim4,0\sim4}\),表示考虑前\(i\)种牌,\(0\sim1\)个对子,\(j\)个\(i-1,i,i+1\)顺子,\(k\)个\(i,i+1,i+2\)顺子,\(0\sim4\)个面子,\(0\sim4\)个杠子,的最大价值,转移枚举下一种牌\(i\)怎么放,可以放杠子,或者放\(i,i+1,i+2\)的顺子同时考虑放对子和刻子,然后最后用对应牌型的dp值更新答案

注意顺子的限制条件,同时建议限制一下状态中牌的总数不超过\(18\)个

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdlib>
  5. #include<cstdio>
  6. #include<vector>
  7. #include<cmath>
  8. #include<ctime>
  9. #include<queue>
  10. #include<map>
  11. #include<set>
  12. #define LL long long
  13. #define db double
  14. using namespace std;
  15. const int N=40;
  16. int rd()
  17. {
  18. int x=0,w=1;char ch=0;
  19. while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
  20. while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
  21. return x*w;
  22. }
  23. map<string,int> id;
  24. char cc[3];
  25. void inii()
  26. {
  27. id["B"]=0;
  28. id["1m"]=1;
  29. id["2m"]=2;
  30. id["3m"]=3;
  31. id["4m"]=4;
  32. id["5m"]=5;
  33. id["6m"]=6;
  34. id["7m"]=7;
  35. id["8m"]=8;
  36. id["9m"]=9;
  37. id["1p"]=10;
  38. id["2p"]=11;
  39. id["3p"]=12;
  40. id["4p"]=13;
  41. id["5p"]=14;
  42. id["6p"]=15;
  43. id["7p"]=16;
  44. id["8p"]=17;
  45. id["9p"]=18;
  46. id["1s"]=19;
  47. id["2s"]=20;
  48. id["3s"]=21;
  49. id["4s"]=22;
  50. id["5s"]=23;
  51. id["6s"]=24;
  52. id["7s"]=25;
  53. id["8s"]=26;
  54. id["9s"]=27;
  55. id["E"]=28;
  56. id["S"]=29;
  57. id["W"]=30;
  58. id["N"]=31;
  59. id["Z"]=32;
  60. id["F"]=33;
  61. }
  62. int c[5][5]={{1},{1,1},{1,2,1},{1,3,3,1},{1,4,6,4,1}},cn[N];
  63. bool qb[N];
  64. int gtws[13]={1,9,10,18,19,27,28,29,30,31,32,0,33};
  65. LL f[2][2][3][3][5][5],qdz[N],ans;
  66. int main()
  67. {
  68. inii();
  69. int T=rd();
  70. while(T--)
  71. {
  72. ans=0;
  73. for(int i=0;i<34;++i) cn[i]=4,qb[i]=0;
  74. while(1)
  75. {
  76. scanf("%s",cc);
  77. if(cc[0]=='0') break;
  78. --cn[id[cc]];
  79. }
  80. while(1)
  81. {
  82. scanf("%s",cc);
  83. if(cc[0]=='0') break;
  84. qb[id[cc]]=1;
  85. }
  86. bool fg=1;
  87. for(int i=0;fg&&i<13;++i) fg=cn[gtws[i]];
  88. if(fg)
  89. {
  90. LL sm=13;
  91. for(int i=0;i<13;++i) sm*=(1ll<<qb[gtws[i]])*cn[gtws[i]];
  92. for(int i=0;i<13;++i)
  93. if(cn[gtws[i]]>=2) ans=max(ans,sm*(1ll<<qb[gtws[i]])*(cn[gtws[i]]-1)/2);
  94. }
  95. int m=0;
  96. for(int i=0;i<34;++i)
  97. if(cn[i]>=2) qdz[++m]=(1ll<<(qb[i]*2))*c[cn[i]][2];
  98. if(m>=7)
  99. {
  100. sort(qdz+1,qdz+m+1);
  101. LL sm=7;
  102. for(int i=1;i<=7;++i) sm*=qdz[m-i+1];
  103. ans=max(ans,sm);
  104. }
  105. memset(f,0,sizeof(f));
  106. int nw=1,la=0;
  107. f[la][0][0][0][0][0]=1;
  108. for(int i=0;i<34;++i)
  109. {
  110. for(int j=0;j<=1;++j)
  111. for(int k=0;k<=2;++k)
  112. for(int l=0;l<=2;++l)
  113. for(int p=0;p<=4&&j*2+p*3<=18;++p)
  114. for(int q=0;q<=4&&j*2+p*3+q*4<=18;++q)
  115. {
  116. if(!f[la][j][k][l][p][q]) continue;
  117. int res=cn[i]-k-l,lm=min(i>=1&&i<=27&&(i-1)%9+1<=7?2:0,res);
  118. for(int o=0;o<=lm&&o<=cn[i+1]-l&&o<=cn[i+2]&&p+o<=4&&j*2+(p+o)*3+q*4<=18;++o)
  119. {
  120. LL dt=1ll<<(o*(qb[i]+qb[i+1]+qb[i+2]));
  121. f[nw][j][l][o][p+o][q]=max(f[nw][j][l][o][p+o][q],f[la][j][k][l][p][q]*dt*c[cn[i]][o+k+l]);
  122. if(o+2<=res&&!j&&(j+1)*2+(p+o)*3+q*4<=18) f[nw][j+1][l][o][p+o][q]=max(f[nw][j+1][l][o][p+o][q],f[la][j][k][l][p][q]*dt*c[cn[i]][o+k+l+2]*(1<<(qb[i]*2)));
  123. if(o+3<=res&&p+o+1<=4&&j*2+(p+o+1)*3+q*4<=18) f[nw][j][l][o][p+o+1][q]=max(f[nw][j][l][o][p+o+1][q],f[la][j][k][l][p][q]*dt*c[cn[i]][o+k+l+3]*(1<<(qb[i]*3)));
  124. }
  125. if(res==4&&q+1<=4&&j*2+p*3+(q+1)*4<=18) f[nw][j][l][0][p][q+1]=max(f[nw][j][l][0][p][q+1],f[la][j][k][l][p][q]*c[cn[i]][4]*(1<<(qb[i]*4)));
  126. f[la][j][k][l][p][q]=0;
  127. }
  128. nw^=1,la^=1;
  129. }
  130. ans=max(ans,f[la][1][0][0][4][0]);
  131. ans=max(ans,f[la][1][0][0][3][1]);
  132. ans=max(ans,f[la][1][0][0][2][2]);
  133. ans=max(ans,f[la][1][0][0][1][3]);
  134. ans=max(ans,f[la][1][0][0][0][4]);
  135. printf("%lld\n",ans);
  136. }
  137. return 0;
  138. }

luogu P5301 [GXOI/GZOI2019]宝牌一大堆的更多相关文章

  1. 【题解】Luogu P5301 [GXOI/GZOI2019]宝牌一大堆

    原题传送门 首先先要学会麻将,然后会发现就是一个暴力dp,分三种情况考虑: 1.非七对子国士无双,设\(dp_{i,j,k,a,b}\)表示看到了第\(i\)种牌,一共有\(j\)个\(i-1\)开头 ...

  2. P5301 [GXOI/GZOI2019]宝牌一大堆

    题目地址:P5301 [GXOI/GZOI2019]宝牌一大堆 这里是官方题解(by lydrainbowcat) 部分分 直接搜索可以得到暴力分,因为所有和牌方案一共只有一千万左右,稍微优化一下数据 ...

  3. [LOJ3084][GXOI/GZOI2019]宝牌一大堆——DP

    题目链接: [GXOI/GZOI2019]宝牌一大堆 求最大值容易想到$DP$,但如果将$7$种和牌都考虑进来的话,$DP$状态不好设,我们将比较特殊的七小对和国士无双单独求,其他的进行$DP$. 观 ...

  4. 【BZOJ5503】[GXOI/GZOI2019]宝牌一大堆(动态规划)

    [BZOJ5503][GXOI/GZOI2019]宝牌一大堆(动态规划) 题面 BZOJ 洛谷 题解 首先特殊牌型直接特判. 然后剩下的部分可以直接\(dp\),直接把所有可以存的全部带进去大力\(d ...

  5. [GXOI/GZOI2019]宝牌一大堆(dp)

    luogu     bzoj 这个麻将题还算挺友善的,比隔壁zjoi的要好得多... 比较正常的做法是五维dp 但事实上六维dp也是完全不会被卡的 七对子选权值最高的七个,国士无双直接$13^2$暴力 ...

  6. 题解 P5301 【[GXOI/GZOI2019]宝牌一大堆】

    这道题除了非常恶心以外也没有什么非常让人恶心的地方 当然一定要说有的话还是有的,就是这题和咱 ZJOI 的 mahjong 真的是好像的说~ 于是就想说这道题出题人应该被 锕 掉 noteskey 整 ...

  7. [luogu 5301][bzoj 5503] [GXOI/GZOI2019] 宝牌一大堆

    题面 好像ZJOI也考了一道麻将, 这是要发扬中华民族的赌博传统吗??? 暴搜都不会打, 看到题目就自闭了, 考完出来之后看题解, \(dp\), 可惜自己想不出来... 对于国士无双(脑子中闪过了韩 ...

  8. [GXOI/GZOI2019]宝牌一大堆

    感觉比ZJOI的麻将要休闲很多啊. 这个题就是一个最优化问题,没有面子的特殊牌型可以直接用复杂度较低的贪心判掉. 有面子的话就是一个经典dp.(曾经还在ZJOI写过这个毒瘤东西 大概就是存一下对子,面 ...

  9. [GX/GZOI2019]宝牌一大堆(DP)

    出这种麻将题有意思吗? 乍看很难实则很水,就是麻将式DP,想必大家很熟悉了吧.首先把“国士无双”和“七对子”两种牌型判掉,然后观察牌胡的形式,发现每多一张牌实际上就是把1个面子变成1个杠子,然后可以直 ...

随机推荐

  1. Git拉取、提交、迁出、合并、删除分之命令

    #拉取代码 git clone -b 分之名称 git地址 #提交代码 git add . //:注释,if是第一次提交: $ git add --all . (请注意后面有个英文点(表示是当前目录) ...

  2. Linux学习笔记(一)----Ubuntu下的apt命令

    一.原理与目录 先介绍几个和apt-get相关的目录: /var/lib/dpkg/available文件的内容是软件包的描述信息, 该软件包括当前系统所使用的 Debian 安装源中的所有软件包,其 ...

  3. parquet文件 读取 原理

    学习一下parquet存储结构 原理 以及使用

  4. 获取与esp8266连接的客户端的Mac地址 IP 端口 控制停止等问题

    两个关键的库 ESP8266WebServer.h WiFiClient.h ESP8266WiFiAP.cpp C:\Users\dongdong\Desktop\Arduino-master\li ...

  5. SQL Server的JOIN是支持使用小括号修改执行顺序的

    假如现在我们的SQL Server数据库中有三个表:[T_A].[T_B]和[T_C],它们的建表语句如下: --建表语句[T_A] CREATE TABLE [dbo].[T_A]( [ID_A] ...

  6. AI要被祭天了!删Bug,删着删着把全部代码都删了

    近日,美国版的“大众点评”,本想训练 AI 来消除 bug,结果它把所有内容删除了... Yelp 在其最新更新的 App 中写道: “我们为本周使用该app遇到问题的用户致歉.我们训练了一个神经网络 ...

  7. 09-JavaScript之伪数组arguments

    JavaScript之伪数组arguments arguments代表的是实参.有个讲究的地方是:arguments只在函数中使用. 1.返回函数实参的个数 使用argument.length方法返回 ...

  8. jexus部署webapi或mvc报错处理

    1路径错误:因为Windows和Linux的路径问题大小写问题. 解决: 修改jexus下的jws把export MONO_IOMAP=all注释去掉放出来. 2, 解决: 卸载

  9. Spring表达式语言SpEL

    Spring表达式语言,简称SpEL,是一个支持运行时查询和操作对象图的强大的表达式语言.语法类似于EL:SpEL使用#{…}作为定界符,所有在大括号中的字符都将被认为是SpEL SpEL为bean属 ...

  10. MyBatis的接口式编程Demo

    很久没细看过MyBatis了,时间一长就容易忘记. 下面是一个接口式编程的例子. 这里的例子一共分为4步: 1 首先要有一个namespace为接口的全类名的映射文件,该例中是 IMyUser.xml ...