博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
题解 P5301 【[GXOI/GZOI2019]宝牌一大堆】
阅读量:5126 次
发布时间:2019-06-13

本文共 3163 字,大约阅读时间需要 10 分钟。

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

当然一定要说有的话还是有的,就是这题和咱 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
#define Rg register#define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i
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); //否则加贡献 else if(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<
=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

你可能感兴趣的文章
php下载文件添加header响应头
查看>>
logrotate
查看>>
ORACLE快速遍历树及join基表很大的性能问题
查看>>
以太网交换机
查看>>
DOM
查看>>
ROS学习笔记四:用C++编写ROS发布与订阅
查看>>
点击回车事件(登录)
查看>>
Windows7睡眠后自动唤醒
查看>>
Jq_网站顶部定时折叠广告
查看>>
GCD与LCM【数论】
查看>>
构建之法现代软件概述
查看>>
实现进程守护 脚本命令
查看>>
snappy
查看>>
CLR via C# 阅读 笔记
查看>>
互斥锁
查看>>
arp欺骗技术
查看>>
admin——django自带数据库管理工具
查看>>
怎么配置SQLServer2005以允许远程连接
查看>>
NSString 中包含中文字符时转换为NSURL
查看>>
莫名其秒的Cannot load JDBC driver class 'com.mysql.jdbc.Driv
查看>>