感觉比ZJOI的麻将要休闲很多啊。

这个题就是一个最优化问题,没有面子的特殊牌型可以直接用复杂度较低的贪心判掉。

有面子的话就是一个经典dp。(曾经还在ZJOI写过这个毒瘤东西

大概就是存一下对子,面子,杠子的个数,再记一下上两个位置剩余的牌的个数,转移非常简单。

写起来挺爽的。

#include<bits/stdc++.h>
#define N 55
#define eps 1e-7
#define inf 1e18+7
#define db double
#define ll long long
#define ldb long double
using namespace std;
inline ll read()
{char ch=0;ll x=0,flag=1;while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}return x*flag;
}
map<string,ll>mp;
bool h[N],flag[N],chk[N][N][N];
ll tot,ans,a[N],b[N],cnt[N],C[N][N];
void prepare()
{//万 mp["1m"]=++tot;mp["2m"]=++tot;mp["3m"]=++tot;mp["4m"]=++tot;mp["5m"]=++tot;mp["6m"]=++tot;mp["7m"]=++tot;mp["8m"]=++tot;mp["9m"]=++tot;//筒 mp["1p"]=++tot;mp["2p"]=++tot;mp["3p"]=++tot;mp["4p"]=++tot;mp["5p"]=++tot;mp["6p"]=++tot;mp["7p"]=++tot;mp["8p"]=++tot;mp["9p"]=++tot;//索mp["1s"]=++tot;mp["2s"]=++tot;mp["3s"]=++tot;mp["4s"]=++tot;mp["5s"]=++tot;mp["6s"]=++tot;mp["7s"]=++tot;mp["8s"]=++tot;mp["9s"]=++tot; //其它mp["E"]=++tot;mp["S"]=++tot;mp["W"]=++tot;mp["N"]=++tot;mp["Z"]=++tot;mp["B"]=++tot;mp["F"]=++tot;//组合数 for(ll i=0;i<=10;i++){C[i][0]=1;for(ll j=1;j<=i;j++)C[i][j]=C[i-1][j-1]+C[i-1][j];}//预处理可以凑面子的位置for(ll i=1;i<=27;i++)h[i]=true;h[1]=h[2]=h[10]=h[11]=h[19]=h[20]=false;//预处理合法状态 chk[1][4][0]=chk[1][3][1]=chk[1][2][2]=chk[1][1][3]=true;for(ll i=1;i>=0;i--)for(ll j=4;j>=0;j--)for(ll k=4;k>=0;k--)if(chk[i][j][k]){if(i)chk[i-1][j][k]=true;if(j)chk[i][j-1][k]=true;if(k)chk[i][j][k-1]=true;}
}
void clear()
{ans=0;for(ll i=0;i<=4;i++)a[i]=b[i]=0;for(ll i=1;i<=tot;i++)cnt[i]=4,flag[i]=false;
}
ll ksm(ll x,ll k)
{ll ans=1;while(k){if(k&1)ans*=x;k>>=1;x*=x;}return ans;
}
ll work1()//七对子
{ll k,now=0,ans=7;k=min(a[4],7-now);now+=k;ans*=ksm(24,k);k=min(a[3],7-now);now+=k;ans*=ksm(12,k);k=min(b[4],7-now);now+=k;ans*=ksm(6,k);k=min(a[2],7-now);now+=k;ans*=ksm(4,k);k=min(b[3],7-now);now+=k;ans*=ksm(3,k);k=min(b[2],7-now);now+=k;ans*=ksm(1,k);k=min(a[4],7-now);now+=k;ans/=ksm(6,k);ans*=ksm(4,k);k=min(b[4],7-now);now+=k;ans/=ksm(6,k);ans*=ksm(1,k);if(now==7)return ans;else return -inf;
}
ll work2()//国士无双
{bool ok=false;ll p[20],now=13,ans=0;p[1]=1;p[2]=9;p[3]=10;p[4]=18;p[5]=19;p[6]=27;p[7]=28;p[8]=29;p[9]=30;p[10]=31;p[11]=32;p[12]=33;p[13]=34;for(ll i=1;i<=13;i++){ll x=p[i];if(!cnt[x])return -inf;if(cnt[x]>=2)ok=true;now*=cnt[x];if(flag[x])now*=2;}if(!ok)return -inf; for(ll i=1;i<=13;i++){ll x=p[i];if(cnt[x]==2)ans=max(ans,(now/2)*1*(flag[x]?2:1));if(cnt[x]==3)ans=max(ans,(now/3)*3*(flag[x]?2:1));if(cnt[x]==4)ans=max(ans,(now/4)*6*(flag[x]?2:1));}return ans;
}
ll dp[2][5][4][5][5][5],DP[2][5][4][5][5][5];
void update(ll &x,ll k){x=max(x,k);}
ll work3()//各种杠子+面子+雀头
{memset(DP,-1,sizeof(DP));DP[0][0][0][cnt[1]][0][0]=1;for(ll i=1;i<=tot;i++){ll lx=cnt[i],ly=(i<=1)?0:cnt[i-1],lz=(i<=2)?0:cnt[i-2];for(ll a=0;a<=1;a++)for(ll b=0;b<=4;b++)for(ll c=0;c<=3;c++)if(chk[a][b][c])for(ll x=0;x<=4;x++)for(ll y=0;y<=4;y++)for(ll z=0;z<=4;z++)dp[a][b][c][x][y][z]=DP[a][b][c][x][y][z],DP[a][b][c][x][y][z]=-1;for(ll a=0;a<=1;a++)for(ll b=0;b<=4;b++)for(ll c=0;c<=3;c++)if(chk[a][b][c])for(ll x=0;x<=lx;x++)for(ll y=0;y<=ly;y++)for(ll z=0;z<=lz;z++){ll o=dp[a][b][c][x][y][z];if(o<=0)continue;if(x>=2&&a!=1)update(dp[a+1][b][c][x-2][y][z],o);if(x>=3&&b!=4)update(dp[a][b+1][c][x-3][y][z],o);if(x>=4&&c!=3)update(dp[a][b][c+1][x-4][y][z],o);if(x&&y&&z&&b!=4&&h[i])update(dp[a][b+1][c][x-1][y-1][z-1],o);if(i<=2)update(DP[a][b][c][cnt[i+1]][x][y],o);else{ll k=cnt[i-2]-z;o*=C[cnt[i-2]][k]*(flag[i-2]?ksm(2,k):1);update(DP[a][b][c][cnt[i+1]][x][y],o);}}}ll ans=0;for(ll a=0;a<=1;a++)for(ll b=0;b<=4;b++)for(ll c=0;c<=3;c++)if(chk[a][b][c])for(ll x=0;x<=cnt[tot-0];x++)for(ll y=0;y<=cnt[tot-1];y++)for(ll z=0;z<=cnt[tot-2];z++){ll ka=cnt[tot-0]-x,kb=cnt[tot-1]-y,kc=cnt[tot-2]-z;dp[a][b][c][x][y][z]*=C[cnt[tot-0]][ka]*(flag[tot-0]?ksm(2,ka):1);dp[a][b][c][x][y][z]*=C[cnt[tot-1]][kb]*(flag[tot-1]?ksm(2,kb):1);dp[a][b][c][x][y][z]*=C[cnt[tot-2]][kc]*(flag[tot-2]?ksm(2,kc):1);if(a==1&&b==4&&c==0)ans=max(ans,dp[a][b][c][x][y][z]);if(a==1&&b==3&&c==1)ans=max(ans,dp[a][b][c][x][y][z]);if(a==1&&b==1&&c==3)ans=max(ans,dp[a][b][c][x][y][z]);if(a==1&&b==4&&c==0)ans=max(ans,dp[a][b][c][x][y][z]);}return ans;
}
ll work4()//特殊处理4杠子+1对子
{ll ans=-inf;for(ll i=2;i<=4;i++)if(a[i]){a[i]--;ll k,v=4*C[i][2],now=0;k=min(a[4],4-now);now+=k;v*=ksm(16,k);k=min(b[4],4-now);now+=k;v*=ksm(1,k);if(now==4)ans=max(ans,v);a[i]++;}for(ll i=2;i<=4;i++)if(b[i]){b[i]--;ll k,v=1*C[i][2],now=0;k=min(a[4],4-now);now+=k;v*=ksm(16,k);k=min(b[4],4-now);now+=k;v*=ksm(1,k);if(now==4)ans=max(ans,v);b[i]++;}   return ans;
}
void solve()
{clear();    while(true){string s;cin>>s;if(s[0]=='0')break;cnt[mp[s]]--;}while(true){string s;cin>>s;if(s[0]=='0')break;flag[mp[s]]=true;}for(ll i=1;i<=tot;i++)if(flag[i])a[cnt[i]]++;else b[cnt[i]]++;ans=max(ans,work1());ans=max(ans,work2());ans=max(ans,work3());ans=max(ans,work4());printf("%lld\n",ans);
}
int main()
{prepare();ll t=read();for(ll i=1;i<=t;i++)solve();return 0;
}

转载于:https://www.cnblogs.com/Creed-qwq/p/10772166.html

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

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

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

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

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

  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题解

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

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

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

  8. [数据结构专训][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 ...

  9. 【LOJ】#3086. 「GXOI / GZOI2019」逼死强迫症

    LOJ#3086. 「GXOI / GZOI2019」逼死强迫症 这个就是设状态为\(S,j\)表示轮廓线为\(S\),然后用的1×1个数为j 列出矩阵转移 这样会算重两个边相邻的,只要算出斐波那契数 ...

最新文章

  1. unity 200.8m yoy_专场分享会|大会最新Unity、中创文旅专场预告来啦!
  2. python 获取当前时间 时间差
  3. hihocoder 1320 压缩字符串(字符串+dp)
  4. 数据库连接池——C3P0:数据库连接池技术
  5. CL_CRM_REPORT_QUESTION call CRM_REPORT_RF_CHECK_AUTHORITY
  6. scope python_Python标准库Scope
  7. pandas plot label_Python+Pandas | 分析比特币与股票市场的关系
  8. 教你把gps服务器修改为中国加速搜星,Android的GPS加速搜星的原理和方法
  9. java s类型_javasript基础——数据类型与数据类型转换
  10. 设计一个几何图形的面积计算器,希望这个计算器可以计算圆和矩形等图形的面积
  11. Android开发笔记(一百八十一)使用CameraX拍照
  12. C语言贪心算法——找钱
  13. 关于微信小程序中的取整
  14. 使用CSS过滤器让透明的彩色png图像变纯白
  15. 最新FL Studio 21中文版发布啦!全新的FL音频剪辑封套、主题和插件
  16. 微型计算机原理与应用课件,微机原理与应用课件
  17. Python爬虫抓取某音乐网站MP3(下载歌曲、存入Sqlite)
  18. ARP攻击与ARP欺骗
  19. 【转】Python之optparse模块OptionParser的使用方法
  20. logins登录项目

热门文章

  1. 前端面试题整理 (ES6篇)
  2. React实现实时/局部刷新
  3. win10系统开启局域网共享
  4. 阿里王坚眼中的互联网、数据和AI
  5. Windows10 插入耳机没声音,安装驱动无效问题解决
  6. 专家修炼-学习的方法
  7. 微信小程序-如何引入地图组件及显示当前所在位置
  8. 面试官:请你谈谈ConcurrentHashMap
  9. 3D建模角色男人头雕刻 | 不要再花钱买教程啦
  10. 网站的权重怎么计算以及网站降权的分析处理方法