题意

LOJ传送门

题解

可以发现「七对子」 和 「国士无双」直接暴力就行了。

唯一的就是剩下的"3*4+2"。

考试的时候写了个爆搜剪枝,开了O2有50pts。写的时候发现可以DP,但是没写。

然后下来写了发现就4个转移。。。

用\(dp[i][j][k][a][b][c]\)表示当考虑前\(i\)张牌,有\(j\)个雀头,\(k\)个面子,\(i-2\)用了\(a\)张,\(i-1\)用了\(b\)张,\(i\)用了\(c\)张时,前\(i-3\)张牌的最大分数。

注意这里是"前\(i-3\)张牌的最大分数",也就是没有计算\(a,b,c\)这最后\(3\)种牌的贡献。

有个性质就是杠子一定不会选,因为选杠子一定劣于面子。

因为\(C(4,4)=1<C(4,3)=4\),就算这张牌是宝牌,杠子的贡献是\(C(4,4)*2^4<C(4,3)*2^3\)

所以我们没有考虑杠子。

上代码

CODE

luogu上开了O2才过

#include <bits/stdc++.h>
using namespace std;
inline int getid(char *s) {
if(isdigit(s[0])) {
int re = s[0]-'0';
if(s[1] == 'm') return re;
if(s[1] == 'p') return 9+re;
if(s[1] == 's') return 18+re;
}
if(s[0] == 'E') return 28;
if(s[0] == 'S') return 29;
if(s[0] == 'W') return 30;
if(s[0] == 'N') return 31;
if(s[0] == 'Z') return 32;
if(s[0] == 'B') return 33;
if(s[0] == 'F') return 34;
}
typedef long long LL;
int cnt[50], bel[50];
LL ans, c[5][5], pw6[10];
bool bao[50]; int arr13[14] = { 0, 1, 9, 10, 18, 19, 27, 28, 29, 30, 31, 32, 33, 34 }; //指定的13张牌的编号
void solve13() {
bool flg = 1;
for(int i = 1; i <= 13; ++i) flg &= bool(cnt[arr13[i]]);
if(flg) {
LL now = 13;
for(int i = 1; i <= 13; ++i)
now = now * c[cnt[arr13[i]]][1] * (bao[arr13[i]] ? 2 : 1);
for(int i = 1; i <= 13; ++i)
ans = max(ans, now / c[cnt[arr13[i]]][1] * c[cnt[arr13[i]]][2] * (bao[arr13[i]] ? 2 : 1));
}
} void dfs(int i, int j, LL now) { //暴力枚举七对子
if(j == 7) { ans = max(now, ans); return; }
if(i > 34) return;
LL tmp = now*pw6[7-j]*(1ll<<((7-j)<<1)); //剪枝,预估之后的最大值,如果小于等于当前答案就不用了搜下去了
if(tmp <= ans) return;
if(cnt[i] >= 2) {
cnt[i] -= 2;
dfs(i+1, j+1, now*c[cnt[i]+2][2]*(bao[i]?4:1));
cnt[i] += 2;
}
if(tmp <= ans) return;
dfs(i+1, j, now);
}
void solve7() { dfs(1, 0, 7); } LL dp[36][2][5][5][5][5];
inline void upd(LL &x, LL y) { x = y > x ? y : x; }
inline int calc(int i, int j) { return i > 0 ? c[cnt[i]][j] * (bao[i] ? (1<<j) : 1) : 1; } //计算i选j张的贡献
void solve() {
memset(dp, 0, sizeof dp);
dp[1][0][0][0][0][0] = 1;
for(int i = 1; i <= 34; ++i)
for(int j = 0; j < 2; ++j)
for(int k = 0; k <= 4; ++k)
for(int a = 0; a <= 4; ++a)
for(int b = 0; b <= 4; ++b)
for(int c = 0; c <= 4; ++c) {
LL val = dp[i][j][k][a][b][c];
if(val) {
upd(dp[i+1][j][k][b][c][0], val * calc(i-2, a));
if(!j && cnt[i]-c >= 2)
upd(dp[i][j+1][k][a][b][c+2], val);
if(k<4 && cnt[i]-c >= 3)
upd(dp[i][j][k+1][a][b][c+3], val);
if(k<4 && bel[i] && i>2 && bel[i]==bel[i-2] && cnt[i]-c >= 1 && cnt[i-1]-b >= 1 && cnt[i-2]-a >= 1)
upd(dp[i][j][k+1][a+1][b+1][c+1], val);
}
}
for(int a = 0; a <= 4; ++a)
for(int b = 0; b <= 4; ++b)
for(int c = 0; c <= 4; ++c) //最后答案算上a,b,c
upd(ans, dp[34][1][4][a][b][c] * calc(32, a) * calc(33, b) * calc(34, c));
} int main () {
//freopen("doraippai.in", "r", stdin);
// freopen("doraippai.out", "w", stdout);
for(int i = 1; i <= 9; ++i) bel[i] = 1;
for(int i = 10; i <= 18; ++i) bel[i] = 2;
for(int i = 19; i <= 27; ++i) bel[i] = 3;
c[0][0] = 1;
for(int i = 1; i <= 4; ++i) {
c[i][0] = c[i][i] = 1;
for(int j = 1; j < i; ++j)
c[i][j] = c[i-1][j-1] + c[i-1][j];
}
pw6[0] = 1;
for(int i = 1; i <= 7; ++i) pw6[i] = 6ll * pw6[i-1];
int T; scanf("%d", &T); while(T--) {
for(int i = 1; i <= 34; ++i)
cnt[i] = 4, bao[i] = 0;
char s[5];
while(scanf("%s", s), s[0] != '0') {
int num = getid(s);
--cnt[num];
}
while(scanf("%s", s), s[0] != '0') {
int num = getid(s);
bao[num] = 1;
}
ans = 0;
solve13();
solve7();
solve();
printf("%lld\n", ans);
}
}

「GXOI / GZOI2019」宝牌一大堆 (DP)的更多相关文章

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

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

  2. 「GXOI / GZOI2019」简要题解

    「GXOI / GZOI2019」简要题解 LOJ#3083. 「GXOI / GZOI2019」与或和 https://loj.ac/problem/3083 题意:求一个矩阵的所有子矩阵的与和 和 ...

  3. LOJ#3083.「GXOI / GZOI2019」与或和_单调栈_拆位

    #3083. 「GXOI / GZOI2019」与或和 题目大意 给定一个\(N\times N\)的矩阵,求所有子矩阵的\(AND(\&)\)之和.\(OR(|)\)之和. 数据范围 \(1 ...

  4. Loj #3085. 「GXOI / GZOI2019」特技飞行

    Loj #3085. 「GXOI / GZOI2019」特技飞行 题目描述 公元 \(9012\) 年,Z 市的航空基地计划举行一场特技飞行表演.表演的场地可以看作一个二维平面直角坐标系,其中横坐标代 ...

  5. 【LOJ】#3088. 「GXOI / GZOI2019」旧词

    LOJ#3088. 「GXOI / GZOI2019」旧词 不懂啊5e4感觉有点小 就是离线询问,在每个x上挂上y的询问 然后树剖,每个节点维护轻儿子中已经被加入的点的个数个数乘上\(dep[u]^{ ...

  6. 【LOJ】#3087. 「GXOI / GZOI2019」旅行者

    LOJ#3087. 「GXOI / GZOI2019」旅行者 正着求一遍dij,反着求一遍,然后枚举每条边,从u到v,如果到u最近的点和v能到的最近的点不同,那么可以更新答案 没了 #include ...

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

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

  8. 【LOJ】#3085. 「GXOI / GZOI2019」特技飞行

    LOJ#3085. 「GXOI / GZOI2019」特技飞行 这显然是两道题,求\(C\)是一个曼哈顿转切比雪夫后的线段树扫描线 求\(AB\),对向交换最大化和擦身而过最大化一定分别为最大值和最小 ...

  9. 【LOJ】#3083. 「GXOI / GZOI2019」与或和

    LOJ#3083. 「GXOI / GZOI2019」与或和 显然是先拆位,AND的答案是所有数字为1的子矩阵的个数 OR是所有的子矩阵个数减去所有数字为0的子矩阵的个数 子矩阵怎么求可以记录每个位置 ...

随机推荐

  1. 解决ajax跨域请求问题

    自己做网站的时候,经常遇到跨域问题,下面是平时多次实践总结出的解决方法,大家有什么更好的思路,可以相互交流下~ XMLHttpRequest cannot load http://www.imooc. ...

  2. servlet和response

    servlet基础知识 Servlet在内存中是单例----单实例对象一个Servlet类 在内存中最多有一个对象 一个项目有多少功能,将来就有多少Servlet. servlet是自启动的,就是可以 ...

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

    原题传送门 首先先要学会麻将,然后会发现就是一个暴力dp,分三种情况考虑: 1.非七对子国士无双,设\(dp_{i,j,k,a,b}\)表示看到了第\(i\)种牌,一共有\(j\)个\(i-1\)开头 ...

  4. C#项目 App.config 配置文件不同使用环境配置

    问题 部署项目时,常常需要根据不同的环境使用不同的配置文件.例如,在部署网站时可能希望禁用调试选项,并更改连接字符串以使其指向不同的数据库.在创建 Web 项目时,Visual Studio 自动生成 ...

  5. 手机端 关闭当前页面的JS

    JS 代码如下   PS:我找的原代码中, 注释部分是没有注释的,但是调试的时候报错,就注释掉了,因为我只需要微信和支付宝的判定,所以这个地方,就没仔细研究 var isLppzApp = false ...

  6. https相关知识总结

    从园子里看到很多讲解不错的文章,将链接放到这里,备忘 浅析数字证书:https://www.cnblogs.com/hyddd/archive/2009/01/07/1371292.html

  7. 灰度共生矩阵(Gray-level Co-occurrence Matrix,GLCM),矩阵的特征量

    又叫做灰度共现矩阵 Prerequisites 概念 计算方式 对于精度要求高且纹理细密的纹理分布,我们取像素间距为d=1d=1,以下是方向的说明: 我们来看,matlab内置工具箱中的灰度共生矩阵的 ...

  8. 分布式图片服务器FastDFS

    1. 什么是FastDFS FastDFS 是用 c 语言编写的一款开源的分布式文件系统.FastDFS 为互联网量身定制,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标,使 ...

  9. jQuery---jq操作标签文本(html(),text()),jq操作文档标签(插入,删除,修改),克隆,,jq操作属性,jq操作class属性,jq操作表单value,jq操作css,jq操作盒子(重要),jq操作滚动条

    jQuery---jq操作标签文本(html(),text()),jq操作文档标签(插入,删除,修改),克隆,,jq操作属性,jq操作class属性,jq操作表单value,jq操作css,jq操作盒 ...

  10. Nginx中的break和last

    rewrite中的break和last 两个指令用法相同,但含义不同,需要放到rewrite规则的末尾,用来控制重写后的链接是否继续被nginx配置执行(主要是rewrite.return指令). 示 ...