题目大意

  给你一副手牌,没有飞机带翅膀,按斗地主的规则,求将所有牌打出的最少次数。

题解

先不考虑顺子

  我们已经知道花色对牌没有影响,那么如果不考虑顺子,每个牌具体是什么数字我们也用不着知道,我们关心的只有牌堆中单张、对子、棒子、炸弹、王的个数。因此我们可以用$f(k_1,k_2,k_3,k_4,k_x)$表示当有$k_1$个单张,$k_2$个对子,$k_3$个棒,$k_4$个炸弹,$k_x$个王时,将牌全部打出的最少次数。而显然这是可以进行DP的。转移方式为:要么不拆牌而出牌,要么拆牌。

递推的顺序?

  看以下拆牌的递推式:

                        if (k2)//将二拆成两个单张
UpdMin(cur, F[k1 + 2][k2 - 1][k3][k4][kx]);
if (k3)//将三拆成一个单张和一对
UpdMin(cur, F[k1 + 1][k2 + 1][k3 - 1][k4][kx]);
if (k4)//将四拆成一个单张和一棒
UpdMin(cur, F[k1 + 1][k2][k3 + 1][k4 - 1][kx]);
if (k4)//将四拆成两对
UpdMin(cur, F[k1][k2 + 2][k3][k4 - 1][kx]);

  我们从外到里考虑。最外层不可以从+1处转移,因此我们把$k_4$选为最外层。此时,从$k_4-1$处的转移就都合法了,我们看从$k_4$转移时,第二层不可以从+1处转移。故第二层选$k_3$。此时,从$k3-1$处的转移就都合法了。当从$k_3$处转移时,第三层不可以从+1处转移……因此,递推顺序为$k_4\rightarrow k_3\rightarrow k_2\rightarrow k_1\rightarrow k_x$。

考虑顺子呢?

  枚举所有出顺子的方式(暴力搜顺子),然后再在剩余的牌中查DP表即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
using namespace std; #define UpdMin(x, y) x = min(x, y)
const int MAX_ID = 27, MAX_IDCNT = 7, INF = 0x3f3f3f3f;
const int IdBegin = 1, IdShunziEnd = 12, IdLast = 13, MaxUnitLen = 3;
const int UnitCnt[4] = { 0, 5, 3, 2 };
int F[MAX_ID][MAX_ID][MAX_ID][MAX_ID][MAX_ID];
int IdCnt[MAX_ID], IdCnt_Cnt[MAX_IDCNT];
int CardCnt, Ans; void DoShunzi(int shunziCnt, int idBegin, int unitLen, int unitCnt)
{
if (shunziCnt >= Ans)
return;
for (int dId = 0; dId < unitCnt; dId++)
IdCnt[idBegin + dId] -= unitLen;
memset(IdCnt_Cnt, 0, sizeof(IdCnt_Cnt));
for (int id = IdBegin; id <= IdLast; id++)
IdCnt_Cnt[IdCnt[id]]++;
IdCnt_Cnt[0] = IdCnt[0];
UpdMin(Ans, shunziCnt + F[IdCnt_Cnt[1]][IdCnt_Cnt[2]][IdCnt_Cnt[3]][IdCnt_Cnt[4]][IdCnt_Cnt[0]]); for (int unitLen1 = 1; unitLen1 <= IdLast; unitLen1++)
for (int idBegin1 = IdBegin; idBegin1 <= IdShunziEnd; idBegin1++)
for (int unitCnt1 = 1; idBegin1 + unitCnt1 - 1 <= IdShunziEnd && IdCnt[idBegin1 + unitCnt1 - 1] >= unitLen1; unitCnt1++)
if (unitCnt1 >= UnitCnt[unitLen1])
DoShunzi(shunziCnt + 1, idBegin1, unitLen1, unitCnt1); for (int dId = 0; dId < unitCnt; dId++)
IdCnt[idBegin + dId] += unitLen;
} void DP()
{
memset(F, INF, sizeof(F));
F[0][0][0][0][0] = 0;
for (int k4 = 0; k4 <= CardCnt / 4; k4++)
for (int k3 = 0; k3 <= CardCnt / 3; k3++)
for (int k2 = 0; k2 <= CardCnt / 2; k2++)
for (int k1 = 0; k1 <= CardCnt; k1++)
for (int kx = 0; kx <= 2; kx++)
{
int &cur = F[k1][k2][k3][k4][kx];
if (kx >= 2)//火箭
UpdMin(cur, F[k1][k2][k3][k4][kx - 2] + 1);
if (k4)//炸弹
UpdMin(cur, F[k1][k2][k3][k4 - 1][kx] + 1);
if (k1)//单张,不是王
UpdMin(cur, F[k1 - 1][k2][k3][k4][kx] + 1);
if (kx)//单张 ,是王
UpdMin(cur, F[k1][k2][k3][k4][kx - 1] + 1);
if (k2)//对子
UpdMin(cur, F[k1][k2 - 1][k3][k4][kx] + 1);
if (k3)//三张
UpdMin(cur, F[k1][k2][k3 - 1][k4][kx] + 1);
if (k3 && k1)//三带一,一不是王
UpdMin(cur, F[k1 - 1][k2][k3 - 1][k4][kx] + 1);
if (k3 && kx)//三带一,一是王
UpdMin(cur, F[k1][k2][k3 - 1][k4][kx - 1] + 1);
if (k3 && k2)//三带二,二都不是王
UpdMin(cur, F[k1][k2 - 1][k3 - 1][k4][kx] + 1);
if (k4 && k1 >= 2)//四带二单,二都不是王
UpdMin(cur, F[k1 - 2][k2][k3][k4 - 1][kx] + 1);
if (k4 && k1 && kx)//四带二单,二中一张不是王,一张是王
UpdMin(cur, F[k1 - 1][k2][k3][k4 - 1][kx - 1] + 1);
if (k4 && k2 >= 2)//四带二对
UpdMin(cur, F[k1][k2 - 2][k3][k4 - 1][kx] + 1); if (k2)//将二拆成两个单张
UpdMin(cur, F[k1 + 2][k2 - 1][k3][k4][kx]);
if (k3)//将三拆成一个单张和一对
UpdMin(cur, F[k1 + 1][k2 + 1][k3 - 1][k4][kx]);
if (k4)//将四拆成一个单张和一棒
UpdMin(cur, F[k1 + 1][k2][k3 + 1][k4 - 1][kx]);
if (k4)//将四拆成两对
UpdMin(cur, F[k1][k2 + 2][k3][k4 - 1][kx]);
}
} int main()
{
int t;
scanf("%d%d", &t, &CardCnt);
DP();
while (t--)
{
Ans = INF;
memset(IdCnt, 0, sizeof(IdCnt));
for (int i = 1; i <= CardCnt; i++)
{
int id, color;
scanf("%d%d", &id, &color);
id =
id == 1 ? 12 :
id == 2 ? 13 :
id == 0 ? 0 :
id - 2;
IdCnt[id]++;
}
DoShunzi(0, 0, 0, 0);
printf("%d\n", Ans);
}
return 0;
}

  

luogu2540 斗地主增强版的更多相关文章

  1. Luogu2540 斗地主增强版(搜索+动态规划)

    单纯的暴搜似乎还是很好写的,然而过不了.出完顺子之后答案是可以dp出来的,于是大力搜然后大力dp就好了. dp时强行讨论完了几乎所有拆牌情况,理性愉悦一发. #include<iostream& ...

  2. Luogu 2540 斗地主增强版(搜索,动态规划)

    Luogu 2540 斗地主增强版(搜索,动态规划) Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游 ...

  3. P2540 斗地主增强版

    P2540斗地主增强版 参考大佬题解 思路:顺子暴力搜,剩下的牌我不会贪心所以用记忆化搜索(或者dp): 注意:双王不能当对,二不算顺子 代码 #include <cstdio> #inc ...

  4. [Luogu2540][NOIP2016]斗地主增强版(搜索+DP)

    增强版就是原版中两鬼不算对子的版本. 先爆搜出完所有对子,剩下的牌DP处理. 考虑每个数码的拆牌情况,最多可能被拆成5种情况:1+1+1+1,1+1+2,1+3,2+2,4.故DP状态数最多为5^13 ...

  5. 洛谷 题解 P2540 【斗地主增强版】

    [分析] 暴力搜顺子,贪心出散牌 为什么顺子要暴力? 玩过斗地主的都知道,并不是出越长的顺子越好,如果你有一组手牌,3,4,5,6,7,6,7,8,9,10,你一下把最长的出了去,你会单两张牌,不如出 ...

  6. 【NOIP2015】斗地主 D1 T3 及 增强版 (送命题)

    恶心送命模拟题 暴搜顺子,DP预处理剩下的. 由于官方数据太水,很多情况没有讨论的都能过普通版本,想要测试自己代码正确性的同学们可以交交这道题,有很多dalao给出了hack数据 : Luogu P2 ...

  7. 将表里的数据批量生成INSERT语句的存储过程 增强版

    将表里的数据批量生成INSERT语句的存储过程 增强版 有时候,我们需要将某个表里的数据全部或者根据查询条件导出来,迁移到另一个相同结构的库中 目前SQL Server里面是没有相关的工具根据查询条件 ...

  8. 最新GHOST XP系统下载旗舰增强版 V2016年

    系统来自:系统妈:http://www.xitongma.com 深度技术GHOST xp系统旗舰增强版 V2016年3月 系统概述 深度技术ghost xp系统旗舰增强版集合微软JAVA虚拟机IE插 ...

  9. 最新深度技术GHOST XP系统旗舰增强版 V2016年

    来自系统妈:http://www.xitongma.com 深度技术GHOST xp系统旗舰增强版 V2016年 系统概述 深度技术ghost xp系统旗舰增强版集合微软JAVA虚拟机IE插件,增强浏 ...

随机推荐

  1. HDU - 4514 湫湫系列故事——设计风景线(并查集判环)

    题目: 随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好. 现在已经勘探确定了n ...

  2. ID字段不采用数据库自增长的几点理由

    一个小程序,最初采用了 SqlServer 数据库,后来为了便于部署,转而采用了 Firebird 嵌入式数据库.在重构代码转到 Firebird 的过程中,对“数据实体的数据表的ID字段是否应该使用 ...

  3. python 1-1模块介绍和使用

    1. 什么是模块 1.1 模块就是一系列功能的集合体 1.1.1 模块有三种来源 1.内置的模块 2.第三方的模块 3.自定义模块 1.1.2 模块的格式: 1.使用Python编写的.py文件 2. ...

  4. [Python3网络爬虫开发实战] 1.8.2-Scrapy的安装

    Scrapy是一个十分强大的爬虫框架,依赖的库比较多,至少需要依赖的库有Twisted 14.0.lxml 3.4和pyOpenSSL 0.14.在不同的平台环境下,它所依赖的库也各不相同,所以在安装 ...

  5. 关于ie8下disabled属性:字体颜色问题

    在ie8下,input/textarea输入框如果使用disabled属性,字体的颜色会变灰,这时我们可以使用另一种方法实现它. 不使用disabled,用readonly代替: input[read ...

  6. Buffer.isBuffer()详解

    Buffer.isBuffer(obj) obj {Object} 返回:{Boolean} 如果 obj 是一个 Buffer 则返回 true.

  7. Python之目录结构

    Python之目录结构 项目名project_name project_name -|--bin (可执行文件) --|--start.py import os,sys #设置环境变量 BASE_DI ...

  8. admin——django自带数据库管理工具

    admin是Django自带的数据库管理工具,是一个app 在admin.py中可以自己定制类来使admin数据库管理页面展现自己想要查看的信息 models.py from django.db im ...

  9. 详解SpringBoot 添加对JSP的支持(附常见坑点)

    序言: SpringBoot默认不支持JSP,如果想在项目中使用,需要进行相关初始化工作.为了方便大家更好的开发,本案例可直接作为JSP开发的脚手架工程 SpringBoot+War+JSP . 常见 ...

  10. 莫(meng)比(bi)乌斯反演--BZOJ2301: [HAOI2011]Problem b

    n<=50000个询问,每次问a<=x<=b,c<=y<=d中有多少gcd(x,y)=K的(x,y).a,b,c,d,K<=50000. 这大概是入门题辣..这里记 ...