这道题除了非常恶心以外也没有什么非常让人恶心的地方

当然一定要说有的话还是有的,就是这题和咱 ZJOI 的 mahjong 真的是好像的说~

于是就想说这道题出题人应该被 锕 掉

noteskey

整体的思路就是特判国士无双和七对子,然后 dp 搞普通的胡牌

dp 状态设计和楼上大佬说的一样,就是用一个五维的 \(f[i][j][k][l][p]\) 表示当前处理了前 i 种类型的牌,存在 j 个 面子/杠子 ,以 i-1 开头的顺子要选 k 个,以 i 开头的面子要选 l 个,以及当前是否有 雀头 (用 p 表示)

然后转移就非常的暴力了,反正这里的数据范围也比较小,枚举下状态转移就好了

总的来说就是道 语文 + 码农 + dp 题,虽说没什么思维难度但我不见得能想出来

watch out

这题的字符串读入还是比较毒瘤的...要稍微注意一下不然可能会出事

code

这压行是同样的味道呢~

//by Judge
#include<bits/stdc++.h>
#define Rg register
#define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
#define ll long long
using namespace std;
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[1<<21],*p1=buf,*p2=buf;
inline bool cmax(ll& a,ll b){return a<b?a=b,1:0;}
inline int read(){ int x=0,f=1; char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} inline void reads(string& s){ char c=getchar();for(;!isalpha(c)&&!isdigit(c);c=getchar()); s="";for(;isalpha(c)||isdigit(c);c=getchar()) s+=c;
} char sr[1<<21],z[20];int CCF=-1,Z;
inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;}
inline void print(ll x,char chr='\n'){if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x;while(z[++Z]=x%10+48,x/=10);while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr;
} int t,cnt,a[41],b[41],C[5][5]; ll f[41][5][3][3][2],tp[41];
int gs[14]={0,1,9,10,18,19,27,28,29,30,31,32,33,34}; string c;
inline int id(){ if(c[0]=='B') return 34;if(c[0]=='E') return 28; if(c[0]=='S') return 29; if(c[0]=='W') return 30;if(c[0]=='N') return 31; if(c[0]=='Z') return 32; if(c[0]=='F') return 33;if(c[1]=='m') return c[0]-48; if(c[1]=='p') return c[0]-39; return c[0]-30;
}
int main(){ C[0][0]=1;fp(i,1,4){ C[i][0]=1;fp(j,1,i) C[i][j]=C[i-1][j-1]+C[i-1][j];}fp(T,1,read()){memset(a,0,sizeof a);memset(b,0,sizeof b);memset(f,0,sizeof f);while(1){ reads(c);if(c[0]=='0') break;else ++a[id()];}while(1){ reads(c);if(c[0]=='0') break;else b[id()]=1;}fp(i,1,34) a[i]=4-a[i];ll ans=0;fp(i,1,13){ ll tmp=1; //枚举出现两次的牌 fp(j,1,13) //枚举 13 种牌 if(i==j)if(a[gs[j]]<2) tmp=0; //如果数量不够就让 tmp=0 else tmp*=C[a[gs[j]]][2]*(b[gs[j]]?4:1); //否则加贡献 elseif(a[gs[j]]<1) tmp=0;else tmp*=C[a[gs[j]]][1]*(b[gs[j]]?2:1);cmax(ans,tmp*13);}cnt=0;fp(i,1,34) if(a[i]>=2) tp[++cnt]=C[a[i]][2]*(b[i]?4:1);if(cnt>=7){ //如果牌数大于等于 2 的不止 7 张就可以构成七对子 sort(tp+1,tp+1+cnt); ll tmp=1; //选出权最大的 7 种牌 fp(i,cnt-6,cnt) tmp*=tp[i]; //累乘贡献 cmax(ans,tmp*7);}f[0][0][0][0][0]=1; //初始化边界 fp(i,0,33) fp(j,0,4) for(Rg int k=0;k<3&&j+k<=4;++k){if(k>=1&&(i==9||i==18||i>=27)) break; //不合法开头无法构成顺子 for(Rg int l=0;l<3&&j+k+l<=4;++l){if(l>=1&&(i==9||i==18||i==27)) break;if(f[i][j][k][l][0]||f[i][j][k][l][1]) fp(u,k+l,a[i+1]){ll tmp=C[a[i+1]][u]*(b[i+1]?(1<<u):1); //计算贡献 // 四种转移 if(j+u<=4&&u-k-l<3) cmax(f[i+1][j+k][l][u-k-l][0],f[i][j][k][l][0]*tmp),cmax(f[i+1][j+k][l][u-k-l][1],f[i][j][k][l][1]*tmp);if(u-k-l-2>=0&&j+u-2<=4)cmax(f[i+1][j+k][l][u-k-l-2][1],f[i][j][k][l][0]*tmp);if(u-k-l-3>=0&&j+u-2<=4)cmax(f[i+1][j+k+1][l][u-k-l-3][0],f[i][j][k][l][0]*tmp),cmax(f[i+1][j+k+1][l][u-k-l-3][1],f[i][j][k][l][1]*tmp);if(u==4&&!k&&!l&&j<=3)cmax(f[i+1][j+1][0][0][0],f[i][j][k][l][0]*tmp),cmax(f[i+1][j+1][0][0][1],f[i][j][k][l][1]*tmp);}}}cmax(ans,f[34][4][0][0][1]),print(ans);} return Ot(),0;
}

转载于:https://www.cnblogs.com/Judge/p/10749200.html

题解 P5301 【[GXOI/GZOI2019]宝牌一大堆】相关推荐

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

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

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

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

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

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

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

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

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

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

  6. 题解: [GXOI/GZOI2019]与或和

    我们考虑简化题意: 由于与运算和或运算在每一位上都是独立的,我们可以考虑对每一位进行计算. 子任务1是全1子矩阵 子任务2是总子矩阵个数减去全0子矩阵 然后就是单调栈原题 :洛谷 3400 仓鼠窝 # ...

  7. GXOI/GZOI2019题解

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

  8. 【题解】Luogu-P5303 [GXOI/GZOI2019]逼死强迫症

    P5303 [GXOI/GZOI2019]逼死强迫症 Preface 矩阵题的登峰造极之作. Description 有 TTT 组数据. 对于每组数据,给定正整数 NNN,请求出用 (N−1)(N- ...

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

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

最新文章

  1. 阿里、拼多多P8面试分享!
  2. LaTeX入门最终集 :LaTeX格式的调整LaTeX中怎么打出数学公式LaTeX的各种上下标
  3. Leetcode 116. 填充每个节点的下一个右侧节点指针 解题思路及C++实现
  4. HDU - 2176 取(m堆)石子游戏(尼姆博奕)
  5. Zookeeper分布式锁的使用
  6. 本地上传代码到github仓库
  7. 【unity】Inspector视图中的get/set使用(四)
  8. 上海医疗救治专家组组长:没有讨价还价!
  9. 关于垂直列行值转成水平行值及多列值转合并成单列值
  10. Linux环境变量配置【转】
  11. 谷歌邮箱SMTP Password:SMTP授权码如何获得
  12. html删除子元素无效,如何使用JavaScript删除DOM节点的所有子元素?
  13. netty 远程主机强迫关闭了一个现有的连接。
  14. nohup和的使用/21是什么意思/怎么关闭nohup挂起的程序
  15. Revit二次开发—载入族并交互式放置
  16. Springboot集成Hadoop+Hbase实现企业能源消耗监测大数据分析系统
  17. CVPR 2017:Interspeices Knowledge Transfer for Facial KeyPoint Detection(跨物种脸部关键点检测知识迁移)
  18. Redis工具类封装RedisUtils
  19. 23-Ajax-axios
  20. vue打包中background-image图片路径问题

热门文章

  1. java学习(75):GUL文本框和标签
  2. 实例31:python
  3. firefox android 去更新,Android版Firefox Beta发布更新
  4. python中的sorted是什么意思_python中sort与sorted区别
  5. RO38 –比较RemObjects SDK 通道
  6. Python 黑帽子第二章运行截图
  7. python设置格式模板
  8. 【可持久化线段树】【主席树】[HDU4417]Super Mario
  9. ASP.NET多线程编程(一) 收藏
  10. Javascript玩转Prototype(一)——先谈C#原型模式