[NOIP2015] 斗地主

题目

INPUT

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

OUTPUT

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

SAMPLE

INPUT1

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

OUTPUT1

3

INPUT2

1 17
12 3
4 3
2 3
5 4
10 2
3 3
12 2
0 1
1 3
10 1
6 2
12 1
11 3
5 2
12 4
2 2
7 2

OUTPUT2

6

解题报告

考试时光顾着T3了,看到它时间根本不够= =,拿了小数据特判分走人= =
显然是个暴搜模拟。
首先,显然花色没用,大王小王也可以看做一样的牌,而且,出牌顺序显然没有影响。
那么剩下的就很简单了,我们先出牌多的(正确性显然,因为这样答案一开始就不会很大,然后你可以用当前答案剪枝,因为已经不比当前答案优的解不可能推出最优解,这样,你可以利用较优的解减掉许多劣解,从而优化),并且,显然顺子一般来说要比带牌要优,那么剩下的就很简单了,注意一些出牌规则,不要像某些不会斗地主的小兄弟 (hww:喵喵喵?)一样= =
要注意的是,顺子不一定越长越好,比如考虑这样一副牌:
3 4 5 6 7 8 9 9 10 10 J J
若是以越长越优的话,你会做出先打出顺子3~J,再单打9、10、J的决定,但显然打3~8的顺子加9~J的连对更优一些,所以我们在枚举顺子时,需要枚举所有可能的长度。
  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. using namespace std;
  5. inline int read(){
  6. int sum();
  7. char ch(getchar());
  8. for(;ch<''||ch>'';ch=getchar());
  9. for(;ch>=''&&ch<='';sum=sum*+(ch^),ch=getchar());
  10. return sum;
  11. }
  12. int size[];
  13. int n,ans;
  14. inline int get_val(int x){
  15. if(x==)
  16. return ;
  17. if(x==)
  18. return ;
  19. if(x==)
  20. return ;
  21. return x-;
  22. }
  23. inline int doit(){
  24. int tmp();
  25. int tp[]={};
  26. for(int i=;i<=;i++)
  27. tp[size[i]]++;
  28. while(tp[]&&tp[]>=)
  29. tmp++,tp[]--,tp[]-=;//四带俩对
  30. while(tp[]&&tp[]>=)
  31. tmp++,tp[]--,tp[]-=;//四带俩单
  32. while(tp[]&&tp[]>=)
  33. tmp++,tp[]--,tp[]--;//三带二
  34. while(tp[]&&tp[]>=)
  35. tmp++,tp[]--,tp[]--;//三带一
  36. tmp+=tp[]+tp[]+tp[]+tp[];
  37. return tmp;
  38. }
  39. inline int my_min(int a,int b){
  40. return a<b?a:b;
  41. }
  42. inline void dfs(int cnt){
  43. if(cnt>ans)
  44. return;
  45. int x(doit());
  46. ans=my_min(ans,cnt+x);
  47. for(int i=;i<=;i++){//三顺子
  48. int j;
  49. for(j=i;size[j]>=&&j<=;j++);
  50. if(j-i<)
  51. continue;
  52. for(int k=j;k-i>=;k--){
  53. for(int l=i;l<k;l++)
  54. size[l]-=;
  55. dfs(cnt+);
  56. for(int l=i;l<k;l++)
  57. size[l]+=;
  58. }
  59. }
  60. for(int i=;i<=;i++){//连对
  61. int j;
  62. for(j=i;size[j]>=&&j<=;j++);
  63. if(j-i<)
  64. continue;
  65. for(int k=j;k-i>=;k--){
  66. for(int l=i;l<k;l++)
  67. size[l]-=;
  68. dfs(cnt+);
  69. for(int l=i;l<k;l++)
  70. size[l]+=;
  71. }
  72. }
  73. for(int i=;i<=;i++){//顺子
  74. int j;
  75. for(j=i;size[j]>=&&j<=;j++);
  76. if(j-i<)
  77. continue;
  78. for(int k=j;k-i>=;k--){
  79. for(int l=i;l<k;l++)
  80. size[l]--;
  81. dfs(cnt+);
  82. for(int l=i;l<k;l++)
  83. size[l]++;
  84. }
  85. }
  86. }
  87. inline int gg(){
  88. // freopen("landlords.in","r",stdin);
  89. // freopen("landlords.out","w",stdout);
  90. int T(read());
  91. n=read();
  92. while(T--){
  93. memset(size,,sizeof(size));
  94. for(int i=;i<=n;i++){
  95. int x(read()),y(read());
  96. size[get_val(x)]++;
  97. }
  98. ans=doit();
  99. dfs();
  100. printf("%d\n",ans);
  101. }
  102. return ;
  103. }
  104. int K(gg());
  105. int main(){;}
这一顿暴搜= =

[补档][NOIP2015] 斗地主的更多相关文章

  1. NOIP2015斗地主[DFS 贪心]

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

  2. BZOJ 4325: NOIP2015 斗地主

    4325: NOIP2015 斗地主 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 684  Solved: 456[Submit][Status] ...

  3. NOIP2015 斗地主(搜索+剪枝)

    4325: NOIP2015 斗地主 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 270  Solved: 192[Submit][Status] ...

  4. [补档]暑假集训D6总结

    考试 不是爆零,胜似爆零= = 三道题,就拿了20分,根本没法玩好吧= = 本来以为打了道正解,打了道暴力,加上个特判分,应该不会死的太惨,然而--为啥我只有特判分啊- - 真的是惨. 讲完题觉得题是 ...

  5. LOJ2422 NOIP2015 斗地主 【搜索+贪心】*

    LOJ2422 NOIP2015 斗地主 LINK 题目大意很简单,就是问你斗地主的一分手牌最少多少次出完 然后我们发现对于一种手牌状态,不考虑顺子的情况是可以贪心做掉的 然后我们直接枚举一下顺子出牌 ...

  6. 【BZOJ4325】NOIP2015 斗地主 搜索+剪枝

    [BZOJ4325]NOIP2015 斗地主 Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗 ...

  7. 2106. [NOIP2015] 斗地主

        2106. [NOIP2015] 斗地主 ★★★☆   输入文件:landlords.in   输出文件:landlords.out   简单对比 时间限制:2 s   内存限制:1025 M ...

  8. NOIP2015斗地主题解 7.30考试

    问题 B: NOIP2015 斗地主 时间限制: 3 Sec  内存限制: 1024 MB 题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共 ...

  9. STL 补档

    STL 补档 1.vector 作用:它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据. vector在C++标准模板库中的部分内容,它是 ...

随机推荐

  1. python 数据类型 -- set

    0. set : 无序的,不重复的序列. 1. 创建 set s = set() s = set(list) # list 为可迭代对象的即可 s = {1,23,4} 2. 内建方法 1) 一般方法 ...

  2. ionic 项目中添加modal的步骤流程

    1.首先在templates文件夹下面定义一个新页面,xxx.html,template文件夹在空项目里面是没有的,需要手动添加一个,放在WWW文件夹下面. <ion-modal-view> ...

  3. 转化来的图标用法symbol引用‘font-class引用及Unicode引用

  4. win7开启telnet客户端

  5. MySQL数据库web维护客户端管理工具

    TreeSoft数据库管理系统使用JAVA开发,采用稳定通用的springMVC +JDBC架构,实现基于WEB方式对 MySQL,Oracle,PostgreSQL 等数据库进行维护管理操作. 功能 ...

  6. chrome谷歌浏览器-DevTool开发者工具-详细总结

    目录: 一.概述 1.官方文档 2.打开方法: 3.前言: 二.九个模块: 1.设备模式Device Mode 2.元素面板Elements 3.控制台面板Console 4.源代码面板Sources ...

  7. python 导入informixdb模块

    最近碰到Linux平台使用python连接informixdb数据库的问题.整理如下: 1.安装 informixdb 下载InformixDB-2.5.tar.gz 解压之后,在README文档下看 ...

  8. java中的选择排序之降序排列

    import java.util.Arrays;//必须加载 class Demo{ public static void main(String []args){ int[] arr={3,54,4 ...

  9. jQuery实现的快速查找

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. 团队开发冲刺2-----1day

    第二冲刺阶段团队软件开发第二阶段冲刺 冲刺目标: 1.在第一阶段的基础上完成app内部界面设计. 2.逐步完成app内每一部分内容. 3.对app的实现进一步仔细钻研考虑. 4.对app每一部分内容模 ...