luogu     bzoj

这个麻将题还算挺友善的,比隔壁zjoi的要好得多。。。

比较正常的做法是五维dp

但事实上六维dp也是完全不会被卡的

七对子选权值最高的七个,国士无双直接$13^2$暴力

$dp[i][j][0/1][k][l][m]$表示枚举到了第i张牌,已经凑了j个面子,有无雀头,第i张牌已经用了k张,第i+1张牌用了l张,第i+2张牌用了m张,直接暴力转移。。。

然后你会得到50...

当然需要优化。

优化1:

枚举到dp值为0的直接continue,这样的不合法牌型有很多可以直接跳过。

优化2:

l和m只枚举到2,原因?如果枚举到三个顺子的话那么我们完全可以用三个刻子等效替代。

优化3:

不需要考虑杠。

原因?

$C_{4}^{3}=4$,$C_{4}^{4}=1$

就算这张牌是宝牌选刻子也必然优于杠子

代码就领略一下精神吧(

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<queue>
  4 #define d01(x) for(int x=0;x<2;x++)
  5 using std::priority_queue;
  6 using std::max;
  7 typedef long long lint;
  8 char si[3];
  9 void dm(lint &kk,lint l){kk=max(kk,l);}
 10
 11 int a[35],dora[35];//1~9,10~18,19~27,28,29,30,31,32,33,34
 12 lint dp[36][5][2][5][3][3];
 13 lint dg[36];
 14 lint ans;
 15 int c[5][5]={
 16     1,0,0,0,0,
 17     1,1,0,0,0,
 18     1,2,1,0,0,
 19     1,3,3,1,0,
 20     1,4,6,4,1
 21 };
 22 int yaoku[15]={0,1,9,10,18,19,27,28,29,30,31,32,33,34};
 23 bool isyaoku[35]={0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1};
 24 bool tail[35]={0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1};
 25 void kokushi()
 26 {
 27     int x;
 28     for(int i=1;i<=13;i++)
 29     {
 30         x=yaoku[i];
 31         lint tmp=13;
 32         tmp*=c[a[x]][2]*dora[x]*dora[x];
 33         for(int j=1;j<=13;j++)
 34         {
 35             if(i==j) continue;x=yaoku[j];
 36             tmp*=a[x]*dora[x];
 37         }
 38         ans=max(ans,tmp);
 39     }
 40 }
 41 priority_queue<int> q;
 42 void chitoi()
 43 {
 44     lint tmp=7;
 45     for(int i=1;i<=34;i++) q.push(c[a[i]][2]*dora[i]*dora[i]);
 46     int g;
 47     for(int i=1;i<=7;i++)
 48     {
 49         g=q.top();
 50         q.pop();
 51         tmp*=g;
 52     }
 53     ans=max(ans,tmp);
 54     while(!q.empty()) q.pop();
 55 }
 56
 57
 58 void clr()
 59 {
 60     for(int i=1;i<=35;i++)
 61     {
 62         dg[i]=0;
 63         for(int j=0;j<=4;j++)
 64         {
 65             for(int k=0;k<=4;k++)
 66             {
 67                 for(int l=0;l<=2;l++)
 68                 {
 69                     for(int m=0;m<=2;m++)
 70                     dp[i][j][0][k][l][m]=dp[i][j][1][k][l][m]=0;
 71                 }
 72             }
 73         }
 74     }
 75     for(int i=1;i<=34;i++) a[i]=4,dora[i]=1;
 76     ans=0;
 77     dp[1][0][0][0][0][0]=1;
 78 }
 79 int main()
 80 {
 81     int T;
 82     scanf("%d",&T);
 83     while(T--)
 84     {
 85         clr();
 86         while(1)
 87         {
 88             scanf("%s",si);
 89             if(si[0]=='0') break;
 90             else if(si[1]=='p') a[si[0]-'0']--;
 91             else if(si[1]=='s') a[si[0]-'0'+9]--;
 92             else if(si[1]=='m') a[si[0]-'0'+18]--;
 93             else if(si[0]=='E') a[28]--;
 94             else if(si[0]=='S') a[29]--;
 95             else if(si[0]=='W') a[30]--;
 96             else if(si[0]=='N') a[31]--;
 97             else if(si[0]=='B') a[32]--;
 98             else if(si[0]=='F') a[33]--;
 99             else if(si[0]=='Z') a[34]--;
100         }
101         while(1)
102         {
103             scanf("%s",si);
104             if(si[0]=='0') break;
105             else if(si[1]=='p') dora[si[0]-'0']=2;
106             else if(si[1]=='s') dora[si[0]-'0'+9]=2;
107             else if(si[1]=='m') dora[si[0]-'0'+18]=2;
108             else if(si[0]=='E') dora[28]=2;
109             else if(si[0]=='S') dora[29]=2;
110             else if(si[0]=='W') dora[30]=2;
111             else if(si[0]=='N') dora[31]=2;
112             else if(si[0]=='B') dora[32]=2;
113             else if(si[0]=='F') dora[33]=2;
114             else if(si[0]=='Z') dora[34]=2;
115         }
116         kokushi();//国士无双
117         chitoi();//七对子
118         for(int i=1;i<=34;i++)
119         {
120             for(int j=0;j<=4;j++)
121             {
122                 for(int k=0;k<=4;k++)
123                 {
124                     for(int l=0;l<=2;l++)
125                     {
126                         for(int m=0;m<=2;m++)
127                         {
128                             if(!dp[i][j][0][k][l][m]&&!dp[i][j][1][k][l][m]) continue;
129                             if(a[i]-k>=2) dm(dp[i][j][1][k+2][l][m],dp[i][j][0][k][l][m]/c[a[i]][k]*c[a[i]][k+2]*dora[i]*dora[i]);
130                             //雀头
131                             if(j<4)
132                             {
133                                 if(a[i]-k>=3) d01(o) dm(dp[i][j+1][o][k+3][l][m],dp[i][j][o][k][l][m]/c[a[i]][k]*c[a[i]][k+3]*dora[i]*dora[i]*dora[i]);
134                                 //刻子
135                                 if((!tail[i])&&a[i]-k>0&&a[i+1]-l>0&&a[i+2]-m>0&&l!=2&&m!=2)
136                                     d01(o) dm(dp[i][j+1][o][k+1][l+1][m+1],dp[i][j][o][k][l][m]/c[a[i]][k]*c[a[i]][k+1]*dora[i]/c[a[i+1]][l]*c[a[i+1]][l+1]*dora[i+1]/c[a[i+2]][m]*c[a[i+2]][m+1]*dora[i+2]);
137                                 //顺子
138                             }
139                             dm(dp[i+1][j][0][l][m][0],dp[i][j][0][k][l][m]);
140                             dm(dp[i+1][j][1][l][m][0],dp[i][j][1][k][l][m]);
141                             //转移
142                             if(j==4) dg[i]=max(dg[i],dp[i][j][1][k][l][m]);
143                         }
144                     }
145                 }
146             }
147         }
148         for(int i=1;i<=35;i++) ans=max(ans,dg[i]);
149         printf("%lld\n",ans);
150     }
151     return 0;
152 }

Orz

转载于:https://www.cnblogs.com/rikurika/p/gxoi2019_1.html

[GXOI/GZOI2019]宝牌一大堆(dp)相关推荐

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

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

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

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

  3. 【GXOI/GZOI2019】宝牌一大堆(麻将DP)(贪心)

    传送门 其实还有第三种麻将--四川麻将,规则和其他麻将都不太像,甚至在四川不同地区的规则也不一样. 而关于麻将胡牌的题,能够利用DP解决的,我们可以将这种技巧成为麻将DP 题解: 这篇题解里面用的是川 ...

  4. 【LOJ #3084】【GXOI / GZOI2019】—宝牌一大堆(DP)

    传送门 首先把国士无双和七对子判掉 实际上可以发现杠根本没用 因为(43)>(44)∗2{4\choose 3}>{4\choose 4}*2(34​)>(44​)∗2 设f[i][ ...

  5. LOJ#3084. 「GXOI / GZOI2019」宝牌一大堆(递推)

    题面 传送门 题解 为什么又是麻将啊啊啊!而且还是我最讨厌的爆搜类\(dp\)-- 首先国士无双和七对子是可以直接搞掉的,关键是剩下的,可以看成\(1\)个雀头加\(4\)个杠子或面子 直接\(dp\ ...

  6. GXOI/GZOI2019题解

    GXOI/GZOI2019题解 P5300 [GXOI/GZOI2019]与或和 一眼题.. 显然枚举每个二进制位,答案就变成了全1子矩阵数量. 这个xjb推推,单调栈一下就行了. #include& ...

  7. P5303 [GXOI/GZOI2019]逼死强迫症 题解

    P5303 [GXOI/GZOI2019]逼死强迫症 P5303 [GXOI/GZOI2019]逼死强迫症 说实在的这题不难,但是我推 Dp\tt DpDp 的时候却只和正解相差一点,最后还是看了题解 ...

  8. [GXOI/GZOI2019]旧词——树链剖分+线段树

    题目链接: [GXOI/GZOI2019]旧词 对于$k=1$的情况,可以参见[LNOI2014]LCA,将询问离线然后从$1$号点开始对这个点到根的路径链修改,每次询问就是对询问点到根路径链查询即可 ...

  9. [数据结构专训][GXOI/GZOI2019]旧词,[hdu5118]GRE Words Once More!,[hdu6333]Problem B. Harvest of Apples

    文章目录 T1:[GXOI/GZOI2019]旧词 solution code T2:GRE Words Once More! solution code T3:Problem B. Harvest ...

最新文章

  1. Java项目:仿天猫网上商城项目(java+jsp+servlet+mysql+ajax)
  2. iOS点击空白收回键盘
  3. 珠海市建设工程质量监督检测站
  4. 九九乘法表口诀python-Python 九九乘法表
  5. 利用iframe与Response.Flush实现进度展示效果
  6. 数据库:分布式事务的解决方案
  7. 【PAT乙级】1009 说反话 (20 分)
  8. 图像处理之边缘检测概述
  9. 【转】如何设计动态(不定)字段的产品数据库表?
  10. ​GPLinker:基于GlobalPointer的实体关系联合抽取
  11. 微信小程序支付java视频_【原创】微信小程序支付(普通模式,公众号支付同适用)java后台案例...
  12. 【Tools】MarkDown教程(四)-MarkDown中的UML图
  13. apt-mirror 校验错误文件处理
  14. 微信小程序实现选项卡
  15. 找回密码forget_password
  16. 一牛人总结的开发流程工具组合
  17. vue 音乐盒app_超全!孕期实用母婴类APP推荐......
  18. R语言求一行(列表、list)数据的平均数
  19. 一个基于百度云和图灵的人工智能程序
  20. 2013考研数学复习指南(理工类)-陈文灯

热门文章

  1. web网页死链接检查工具——“Scrutiny 8”
  2. python 数学计算库_Python标准库——数学运算
  3. WebLogic中如何设置Spring Boot项目的属性
  4. SpringBoot应用中JSP的角色及整合
  5. 毕业生,管好你的档案和户口
  6. hive中如何把13位转化为时间_【hive常用函数一】日期函数
  7. 网页编辑PHP变量,编辑文件中的php代码和变量
  8. 计算机基础e卷,大学计算机基础(e卷).doc
  9. RMQ(求区间最值问题)
  10. D. Beautiful numbers