Description

牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、方片的A到K加上大小王的共54张牌来进行的扑克牌游戏。在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,而花色并不对牌的大小产生影响。每一局游戏中,一副手牌由n张牌组成。游戏者每次可以根据规定的牌型进行出牌,首先打光自己的手牌一方取得游戏的胜利。现在,牛牛只想知道,对于自己的若干组手牌,分别最少需要多少次出牌可以将它们打光。请你帮他解决这个问题。需要注意的是,本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。具体规则如下:

Input

第一行包含用空格隔开的2个正整数T,N,表示手牌的组数以及每组手牌的张数。

接下来T组数据,每组数据N行,每行一个非负整数对Ai,Bi,表示一张牌,其中Ai表示牌的数码,Bi表示牌的花色,中间用空格隔开。特别的,我们用1来表示数码A,11表示数码J,12表示数码Q,13表示数码K;黑桃、红心、梅花、方片分别用1-4来表示;小王的表示方法为01,大王的表示方法为02。

Output

共T行,每行一个整数,表示打光第T组手牌的最少次数。

Sample Input

1 8
7 4
8 4
9 1
10 4
11 1
5 1
1 4
1 1

Sample Output

3

HINT

共有1组手牌,包含8张牌:方片7,方片8,黑桃9,方片10,黑桃J,黑桃5,方

片A以及黑桃A。可以通过打单顺子(方片7,方片8,黑桃9,方片10,黑桃J),单张
牌(黑桃5)以及对子牌(黑桃A以及方片A)在3次内打光。
T<=10
N<=23

题解

抓取有用信息:

出牌顺序不影响出牌次数。

30分算法:

1、$T≤100$,$n≤4$;
2、先特判掉三带一的情况,然后有几种不同点数的牌,答案就是几;注意两张王可以看成是相同点数;
3、时间复杂度$O(T*n)$

100分算法:

1、$T≤10$,$n≤23$;
2、既然出牌顺序不影响,那么不妨先出对子,包括单顺、双顺、三顺。具体就是直接暴力枚举每一个顺子,然后出掉,再枚举顺子,再出掉......
3、这样可以过吗?
一个顺子至少有$5$张牌,最多出$4$组顺子,递归层数很小;
然后在一组牌内可以产生$O(K^2)$个顺子,其中$K$表示能成为顺子组成部分的牌的种数,在这里$K=12$,然后这里的复杂度就是$O(K^8)$,看起来很大,其实实测完全可以跑出来;
4、然后就可以不考虑顺子了,那么对于剩下的牌,我们就只能一个一个或者一对一对或者一带一带地出,也就是说出牌次数与牌的点数无关了;
5、那么我们可以预处理一个$dp[a][b][c][d]$,表示手牌有"$d$张单牌,$c$个对子,$b$个三张,$a$个炸弹"的时候,把牌出完的最少次数。
6、可以动态规划求解,$joker$可以拿出单独讨论。
7、时间复杂度$O(n^4+T*K^8)$。

这道题还有数据增强版,就是多考虑几个条件,把牌拆开(详见代码中的$extra$)。

 #include <set>
#include <map>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define LL long long
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
using namespace std;
const int INF = ~0u>>;
const int lenth[] = {, , , }; int n, t;
int card[], f[][][][];
int ans; int getrest(int r1, int r2, int r3, int r4, int joker){
if (joker == ) r1++,joker--;
if (joker) return Min(f[r4][r3][r2][r1+], f[r4][r3][r2][r1]+);
return f[r4][r3][r2][r1];
}
void dfs(int t){
if (t >= ans) return;
int c[] = {};
for (int i = ; i <= ; i++) c[card[i]]++;
ans = Min(ans, t+getrest(c[], c[], c[], c[], card[]));
for (int len = ; len <= ; len++)
  for (int i = ; i <= ; i++){
  int j = i;
  for (;j <= && card[j] >= len; j++){
     card[j] -= len;
    if (j-i+ >= lenth[len]) dfs(t+);
  }
  for (j--; j >= i; j--) card[j] += len;
  }
}
void pre(){
memset(f, /, sizeof(f));
f[][][][] = ;
for (int i = ; i <= n; i++)
  for (int j = ; j <= n; j++)
   for (int p = ; p <= n; p++)
     for (int q = ; q <= n; q++)
      if (i*+j*+p*+q <= n)
     {
       f[i][j][p][q] = i+j+p+q;
       if (i){
       if (p >= ) f[i][j][p][q] = Min(f[i][j][p][q], f[i-][j][p-][q]+);//四带两对
       if (q >= ) f[i][j][p][q] = Min(f[i][j][p][q], f[i-][j][p][q-]+);//四带二
       if (p) f[i][j][p][q] = Min(f[i][j][p][q], f[i][j][p-][q+]);//extra:把对子拆成一个单的
       f[i][j][p][q] = Min(f[i][j][p][q], f[i-][j][p+][q]);//extra:把炸拆成两对
       f[i][j][p][q] = Min(f[i][j][p][q], f[i-][j+][p][q+]);//extra:把炸拆成单张和三张
       f[i][j][p][q] = Min(f[i][j][p][q], f[i-][j][p][q]+);//出炸
       }
       if (j){
       if (p) f[i][j][p][q] = Min(f[i][j][p][q], f[i][j-][p-][q]+);//三带一对
       if (q) f[i][j][p][q] = Min(f[i][j][p][q], f[i][j-][p][q-]+);//三带一
       f[i][j][p][q] = Min(f[i][j][p][q], f[i][j-][p+][q+]);//extra:三拆成二+一
       f[i][j][p][q] = Min(f[i][j][p][q], f[i][j-][p][q]+);//直接出三张
       }
       if (p) f[i][j][p][q] = Min(f[i][j][p][q], f[i][j][p-][q]+);//直接出对子
      if (q) f[i][j][p][q] = Min(f[i][j][p][q], f[i][j][p][q-]+);//直接出单张
     }
} int main(){
scanf("%d%d", &t, &n);
pre();
while (t--){
   memset(card, , sizeof(card));
   int a, b;
  ans = n;
  for (int i = ; i <= n; i++){
   scanf("%d%d", &a, &b);
   if (a == ) card[]++;
   else card[a]++;
   }
   dfs();
   printf("%d\n", ans);
}
return ;
}

[NOIp 2015]斗地主的更多相关文章

  1. Luogu 2668 NOIP 2015 斗地主(搜索,动态规划)

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

  2. 基础算法(搜索):NOIP 2015 斗地主

    Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3& ...

  3. [BZOJ 4325][NOIP 2015] 斗地主

    一道防AK好题 4325: NOIP2015 斗地主 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 820  Solved: 560[Submit] ...

  4. [NOIP 2015] 斗地主 landlord

    想起几个月之前的 noip2015-只会瞎搞-这道题骗了 30 分.T T 题目 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的 A 到 K 加上大小王的共 54 张牌 ...

  5. noip 2015 斗地主 大爆搜!!!

    反正肯定是大模拟 但是每一个可以出的牌都搜一定不是最优的 考虑最特殊的出牌方案:顺子(单,对,三) 每一种方案再加上暴力贪心打出剩下的牌的步数 #include<cstdio> #incl ...

  6. 洛谷 P2668 & P2540 [ noip 2015 ] 斗地主 —— 搜索+贪心

    题目:https://www.luogu.org/problemnew/show/P2668   https://www.luogu.org/problemnew/show/P2540 首先,如果没有 ...

  7. 4632 NOIP[2015] 运输计划

    4632 NOIP[2015] 运输计划  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 大师 Master 题解       题目描述 Description 公元 2044 ...

  8. NOIP 2015

    Prob.1 2015 神奇的幻方 模拟就好了.(这不是noip2017的初赛题么.)代码: #include<cstdio> #include<cstring> #inclu ...

  9. [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告

    [NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...

随机推荐

  1. 外部 Storage Provider - 每天5分钟玩转 Docker 容器技术(149)

    如果 Kubernetes 部署在诸如 AWS.GCE.Azure 等公有云上,可以直接使用云硬盘作为 Volume,下面是 AWS Elastic Block Store 的例子: 要在 Pod 中 ...

  2. 第二次作业-关于Steam游戏平台的简单分析

    1.1 Steam平台的简单介绍 你选择的产品是? 如题,这次的作业我选择了Steam作为分析的对象. 为什么选择该产品作为分析? 我选择数字游戏贩售平台STEAM作为分析对象的原因有以下几点: 1. ...

  3. 201621123062《java程序设计》第三周作业总结

    1.本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用 将这些碎片化的概念.知识点组织起来.请使用工具画出本周学习到的知识点及知识点之间的联系.步骤如下: 1.1写出你认为本周学 ...

  4. 2017-2018-1 我爱学Java 第八周 作业

    团队六七周作业 团队分工 UML图 工具选择 小编(金立清)有话说 参考资料 团队分工 返回目录 UML图 用例图 类图 活动图 状态图 返回目录 工具选择 ProcessOn - 免费在线作图,实时 ...

  5. Python choice() 函数

    Python choice() 函数  Python 数字 描述 choice() 方法返回一个列表,元组或字符串的随机项. 语法 以下是 choice() 方法的语法: import random ...

  6. 北亚关于HP EVA4400/6400/8400/P6000的数据恢复解决方案

    [引言]本文档建立在针对HP EVA的大量测试性研究基础上,所有的细节几乎均为对EVA的破译型研究,目前全球范围内尚未发现类似资料,故可能表述方式和结论并不精确,仅为参考之用.我们公司为研究HP EV ...

  7. 直方图均衡化及matlab实现

    在处理图像时,偶尔会碰到图像的灰度级别集中在某个小范围内的问题,这时候图像很难看清楚.比如下图: 它的灰度级别,我们利用一个直方图可以看出来(横坐标从0到255,表示灰度级别,纵坐标表示每个灰度级别的 ...

  8. JAVA_SE基础——17.方法的重载

    方法重载: 方法重载就是方法名称重复,加载参数不同. 具体规范: 一.方法名一定要相同. 二.方法的参数表必须不同,包括参数的类型或个数,以此区分不同的方法体. 1.如果参数个数不同,就不管它的参数类 ...

  9. JS 实现MVC的写法

    案例:当select 下拉选择框值变化时,显示其值(不是文本) 常规写法 <h3>JavaScript no MVC</h3>  <div>   <selec ...

  10. SpringBoot+Angular2 开发环境搭建

    https://segmentfault.com/a/1190000007921675