Solution -「GXOI / GZOI 2019」宝牌一大堆
Description
Link.
Summarizing the fucking statement is the last thing in the world I ever want to do.
Solution
我们来重新描述一些概念:
- 数字牌:筒条万。
- 顺子:\(3\) 张连续的数字牌。(面子)
- 雀头:\(2\) 张完全一样的牌。
- 刻子:\(3\) 张完全一样的牌。(面子)
- 杠子:\(4\) 张完全一样的牌。
观察发现:杠子在除了 \(14\) 张牌胡牌情况以外的胡牌情况都出现了,于是又发现:\(\binom{4}{3}>\binom{4}{4}\);
于是:
- 对于胡牌的形式,我们只需要考虑「\(3\times4+2\)」「七对子」和「国士无双」。
于是我们只需要三种情况取最大即可。
「七对子」只需要把所有牌型的贡献拉出来,取前 \(7\) 个最大的乘起来即可。
「国士无双」枚举谁来做 \(2\) 个的那个,然后取最大。
「\(3\times4+2\)」
\(\qquad\) 考虑这样一个 DP,设:\(f(i,j,k,a,b,c)\) 为前 \(i\) 个数,\(j\) 个面子,\(k\) 个雀头,第 \(i\) / \(i+1\) / \(i+2\) 张牌用了 \(a\) / \(b\) / \(c\) 张的最优答案(\(k\in\{0,1\}\))。
\(\qquad\) \(\qquad\) 1. 对于雀头:
\]
\(\qquad\) \(\qquad\) \(\qquad\) 其中 \(\text{calc}(x,y)\) 为第 \(x\) 张牌,在手牌中需要出现 \(y\) 次,此时对答案的贡献。
\(\qquad\) \(\qquad\) \(\qquad\) 方程的意义即:去掉把第 \(i\) 种牌之前的贡献,再算上现在算作雀头的贡献。
\(\qquad\) \(\qquad\) 2. 对于刻子:
\]
\(\qquad\) \(\qquad\) \(\qquad\) 基本同上。
\(\qquad\) \(\qquad\) 3. 对于顺子:
\]
\(\qquad\) \(\qquad\) \(\qquad\) 完全同理。
然后就完了。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL koshi[15]={0,1,9,10,18,19,27,28,29,30,31,32,33,34}; // the cards that Kokushimusou needs
const bool chunko[36]={0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1}; // the cards which are able to be jyunko
LL getCard()
{
static char s[10];
scanf("%s",s+1);
if(s[1]=='0') return -1;
else if(!isdigit(s[1]))
{
if(s[1]=='E') return 28;
else if(s[1]=='S') return 29;
else if(s[1]=='W') return 30;
else if(s[1]=='N') return 31;
else if(s[1]=='Z') return 32;
else if(s[1]=='B') return 33;
else return 34;
}
else
{
if(s[2]=='m') return s[1]-'0';
else if(s[2]=='p') return s[1]-'0'+9;
else return s[1]-'0'+18;
}
}
LL t,comb[10][10],cnt[40],trs[40],f[40][5][5][5][5][5];
#define calc(x,f) (((cnt[x])<(f)?0:comb[cnt[x]][f])*(trs[x]?(1<<(f)):1))
LL onesolve() // Seven Pairs
{
vector<LL> pri;
for(LL i=1;i<=34;++i) if(cnt[i]>=2) pri.push_back(calc(i,2));
sort(pri.begin(),pri.end(),greater<LL>());
if(pri.size()<size_t(7)) return 0;
else
{
LL res=7;
for(LL i=0;i<7;++i) res*=pri[i];
return res;
}
}
LL anosolve() // Kokushimusou
{
LL flag=0;
for(LL i=1;i<=13;++i)
{
if(cnt[koshi[i]]>=2) flag=1;
if(cnt[koshi[i]]==0) return 0;
}
if(flag)
{
LL res=0;
for(LL i=1;i<=13;++i)
{
LL tmp=13;
if(cnt[koshi[i]]>=2)
{
for(LL j=1;j<=13;++j) tmp*=calc(koshi[j],(i==j)+1);
}
res=max(res,tmp);
}
return res;
}
else return 0;
}
void getmax(LL &one,LL ano){one=max(one,ano);}
LL exsolve() // 3x4+2
{
#define f(i,j,k,a,b,c) (f[i][j][k][a][b][c])
f(1,0,0,0,0,0)=1;
for(LL i=1;i<=34;++i)
{
for(LL j=0;j<=4;++j)
{
for(LL a=0;a<=4;++a)
{
for(LL b=0;b<=2;++b)
{
for(LL c=0;c<=2;++c)
{
if(cnt[i]-a>=2) getmax(f(i,j,1,a+2,b,c),f(i,j,0,a,b,c)/calc(i,a)*calc(i,a+2));
if(j^4)
{
if(cnt[i]-a>=3)
{
getmax(f(i,j+1,0,a+3,b,c),f(i,j,0,a,b,c)/calc(i,a)*calc(i,a+3));
getmax(f(i,j+1,1,a+3,b,c),f(i,j,1,a,b,c)/calc(i,a)*calc(i,a+3));
}
if(chunko[i]&&cnt[i]-a>=1&&cnt[i+1]-b>=1&&cnt[i+2]-c>=1&&(b^2)&&(c^2))
{
getmax(f(i,j+1,0,a+1,b+1,c+1),f(i,j,0,a,b,c)/calc(i,a)/calc(i+1,b)/calc(i+2,c)*calc(i,a+1)*calc(i+1,b+1)*calc(i+2,c+1));
getmax(f(i,j+1,1,a+1,b+1,c+1),f(i,j,1,a,b,c)/calc(i,a)/calc(i+1,b)/calc(i+2,c)*calc(i,a+1)*calc(i+1,b+1)*calc(i+2,c+1));
}
}
getmax(f(i+1,j,0,b,c,0),f(i,j,0,a,b,c));
getmax(f(i+1,j,1,b,c,0),f(i,j,1,a,b,c));
}
}
}
}
}
LL res=0;
for(LL i=1;i<=34;++i)
{
for(LL a=0;a<=4;++a)
{
for(LL b=0;b<=2;++b)
{
for(LL c=0;c<=2;++c) getmax(res,f(i,4,1,a,b,c));
}
}
}
#undef f
return res;
}
int main()
{
for(LL i=0;i<=4;++i) comb[i][0]=comb[i][i]=1;
for(LL i=1;i<=4;++i) for(LL j=1;j<i;++j) comb[i][j]=comb[i-1][j-1]+comb[i-1][j];
scanf("%lld",&t);
while(t--)
{
memset(f,0,sizeof(f));
for(LL i=1;i<=34;++i) cnt[i]=4,trs[i]=0;
LL tmp=getCard();
while(~tmp) --cnt[tmp],tmp=getCard();
tmp=getCard();
while(~tmp) trs[tmp]=1,tmp=getCard();
printf("%lld\n",max(max(onesolve(),anosolve()),exsolve()));
}
return 0;
}
Solution -「GXOI / GZOI 2019」宝牌一大堆的更多相关文章
- 「GXOI / GZOI2019」宝牌一大堆 (DP)
题意 LOJ传送门 题解 可以发现「七对子」 和 「国士无双」直接暴力就行了. 唯一的就是剩下的"3*4+2". 考试的时候写了个爆搜剪枝,开了O2有50pts.写的时候发现可以D ...
- LOJ#3084. 「GXOI / GZOI2019」宝牌一大堆(递推)
题面 传送门 题解 为什么又是麻将啊啊啊!而且还是我最讨厌的爆搜类\(dp\)-- 首先国士无双和七对子是可以直接搞掉的,关键是剩下的,可以看成\(1\)个雀头加\(4\)个杠子或面子 直接\(dp\ ...
- [LOJ3084][GXOI/GZOI2019]宝牌一大堆——DP
题目链接: [GXOI/GZOI2019]宝牌一大堆 求最大值容易想到$DP$,但如果将$7$种和牌都考虑进来的话,$DP$状态不好设,我们将比较特殊的七小对和国士无双单独求,其他的进行$DP$. 观 ...
- P5301 [GXOI/GZOI2019]宝牌一大堆
题目地址:P5301 [GXOI/GZOI2019]宝牌一大堆 这里是官方题解(by lydrainbowcat) 部分分 直接搜索可以得到暴力分,因为所有和牌方案一共只有一千万左右,稍微优化一下数据 ...
- 【BZOJ5503】[GXOI/GZOI2019]宝牌一大堆(动态规划)
[BZOJ5503][GXOI/GZOI2019]宝牌一大堆(动态规划) 题面 BZOJ 洛谷 题解 首先特殊牌型直接特判. 然后剩下的部分可以直接\(dp\),直接把所有可以存的全部带进去大力\(d ...
- [GXOI/GZOI2019]宝牌一大堆(dp)
luogu bzoj 这个麻将题还算挺友善的,比隔壁zjoi的要好得多... 比较正常的做法是五维dp 但事实上六维dp也是完全不会被卡的 七对子选权值最高的七个,国士无双直接$13^2$暴力 ...
- Solution -「多校联训」光影交错
\(\mathcal{Description}\) Link. 一个游戏包含若干次卡牌抽取,每次以 \(p_l\) 的概率得到 \(+1\),\(p_d\) 的概率得到 \(-1\),否则得到 ...
- Solution -「2020.12.26」 模拟赛
0x00 前言 一些吐槽. 考得很变态诶,看每道题平均两秒的时限就知道了... T1 降智了想到后缀懒得打. T2 口胡了假优化,结果和暴力分一样?? T3 黑题还绑点?? \(50 + 80 + 0 ...
- 题解 P5301 【[GXOI/GZOI2019]宝牌一大堆】
这道题除了非常恶心以外也没有什么非常让人恶心的地方 当然一定要说有的话还是有的,就是这题和咱 ZJOI 的 mahjong 真的是好像的说~ 于是就想说这道题出题人应该被 锕 掉 noteskey 整 ...
- luogu P5301 [GXOI/GZOI2019]宝牌一大堆
传送门 wdnm又是打麻将 首先国土无双可以直接枚举哪种牌用了\(2\)次算贡献,然后\(7\)个对子可以把每种牌的对子贡献排序,取最大的\(7\)个,剩下的牌直接暴力枚举是不行的,考虑dp,设\(f ...
随机推荐
- 搭建一个属于自己的springboot项目
一.确定环境 最近公司要上个新系统,指定由我来带两个人进行开发,既然是新项目,那么项目搭建的事就落到我的头上了.现在都是使用springboot进行开发,为此我搭环境使用的是springboot,具体 ...
- 如何在.net6webapi中实现自动依赖注入
IOC/DI IOC(Inversion of Control)控制反转:控制反正是一种设计思想,旨在将程序中的控制权从程序员转移到了容器中.容器负责管理对象之间的依赖关系,使得对象不再直接依赖于其他 ...
- 实例讲解Flink 流处理程序编程模型
摘要:在深入了解 Flink 实时数据处理程序的开发之前,先通过一个简单示例来了解使用 Flink 的 DataStream API 构建有状态流应用程序的过程. 本文分享自华为云社区<Flin ...
- 自然语言处理 Paddle NLP - 预训练语言模型及应用
什么是语言理解? 关于疫情的一段对话: 中国:我们这边快完了 欧洲:我们这边快完了 中国:我们好多了 欧洲:我们好多了 挑战: 语言的复杂性和多样性 多义/同义/歧义现象 灵活多变的表达形式 语言背后 ...
- Hugging News #0616: 有几项非常重要的合作快来围观、最新中文演讲视频回放发布!
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...
- 聊一聊 Rust 的 stack overflow
早上看到了这篇文章 智能指针有可能会让你的应用崩溃, 下面分析一下 会导致 stack overflow 的代码 struct Node<T> { val: T, next: Option ...
- 前端vue仿京东天猫简单好用的瀑布流瀑布流式布局列表组件waterfall
前端vue仿京东天猫简单好用的瀑布流瀑布流式布局列表组件waterfall, 下载完整代码请访问uni-app插件市场址:https://ext.dcloud.net.cn/plugin?id=130 ...
- requests Python中最好用的网络请求工具 基础速记+最佳实践
简介 requests 模块是写python脚本使用频率最高的模块之一.很多人写python第一个使用的模块就是requests,因为它可以做网络爬虫.不仅写爬虫方便,在日常的开发中更是少不了requ ...
- 无法将“Ethernet0”连接到虚拟网络“VMnet8”。
出现这个问题的解决办法,请参考右侧链接:https://blog.csdn.net/big_bigwolf/article/details/79147388
- 1.4 编写简易ShellCode弹窗
在前面的章节中相信读者已经学会了使用Metasploit工具生成自己的ShellCode代码片段了,本章将继续深入探索关于ShellCode的相关知识体系,ShellCode 通常是指一个原始的可执行 ...