题目描述

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

输入

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

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

输出

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

样例输入

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

样例输出

3


题解

搜索

15年的一道神题,然而由于数据太水而各种水过

后来UOJ又出了个“加强”版,可以构造数据,难度远远大于原题

先说一下大体思路吧:就是各种爆搜。

这里爆搜时有些技巧:

1.当不打龙的时候可以直接计算出最优方案,不需要继续搜索。

2.由于打牌的顺序对答案是没有影响的,因此可以先爆搜打出去牌数多的牌型,即先打多龙再打单龙,先打大龙再打小龙。

然后原题就可以直接水过了。。。

下面说“加强”版:

-1.四张的可以拆成两个两张出

-2.四张的可以拆成一个三张一个一张出

-3.三张的可以拆成一个两张一个一张出

-4.两张的可以拆成两个一张出

-5.“火箭”不算对牌

所以在计算不打龙情况下要出多少次时,还需要枚举前4种情况。。。于是写了8个dfs。。。

然后就能水过这两道题了,代码巨丑= =

做完这两道题以后再也不会玩斗地主了。。。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[20] , ans , n , now , cnt[5];
void dfs8()
{
int c1 = cnt[1] , c2 = cnt[2] , c3 = cnt[3] , c4 = cnt[4] , c = 0;
while(c4)
{
c ++ , c4 -- ;
if(c2 >= 2) c2 -= 2;
else if(c1 >= 2) c1 -= 2;
}
while(c3)
{
c ++ , c3 -- ;
if(c2) c2 -- ;
else if(c1) c1 -- ;
}
if(a[15] && a[16] && c1 >= 2) c -- ;
ans = min(ans , now + c + c1 + c2);
}
void dfs7()
{
int i;
for(i = 0 ; i <= cnt[2] ; i ++ )
{
cnt[2] -= i , cnt[1] += i << 1;
dfs8();
cnt[2] += i , cnt[1] -= i << 1;
}
}
void dfs6()
{
int i;
for(i = 0 ; i <= cnt[3] ; i ++ )
{
cnt[3] -= i , cnt[2] += i , cnt[1] += i;
dfs7();
cnt[3] += i , cnt[2] -= i , cnt[1] -= i;
}
}
void dfs5()
{
int i;
for(i = 0 ; i <= cnt[4] ; i ++ )
{
cnt[4] -= i , cnt[3] += i , cnt[1] += i;
dfs6();
cnt[4] += i , cnt[3] -= i , cnt[1] -= i;
}
}
void dfs4()
{
int i;
memset(cnt , 0 , sizeof(cnt));
for(i = 2 ; i <= 16 ; i ++ ) cnt[a[i]] ++ ;
for(i = 0 ; i <= cnt[4] ; i ++ )
{
cnt[4] -= i , cnt[2] += i << 1;
dfs5();
cnt[4] += i , cnt[2] -= i << 1;
}
}
void dfs3(int p , int l)
{
if(now >= ans) return;
int i , j , k;
for(i = min(n , l) ; i >= 5 ; i -- )
{
for(j = (i == l ? p : 3) ; j <= 15 - i ; j ++ )
{
for(k = j ; k < j + i ; k ++ )
if(!a[k])
break;
if(k == j + i)
{
for(k = j ; k < j + i ; k ++ ) a[k] -- , n -- ;
now ++ , dfs3(j , i) , now -- ;
for(k = j ; k < j + i ; k ++ ) a[k] ++ , n ++ ;
}
}
}
dfs4();
}
void dfs2(int p , int l)
{
if(now >= ans) return;
int i , j , k;
for(i = min(n / 2 , l) ; i >= 3 ; i -- )
{
for(j = (i == l ? p : 3) ; j <= 15 - i ; j ++ )
{
for(k = j ; k < j + i ; k ++ )
if(a[k] < 2)
break;
if(k == j + i)
{
for(k = j ; k < j + i ; k ++ ) a[k] -= 2 , n -= 2;
now ++ , dfs2(j , i) , now -- ;
for(k = j ; k < j + i ; k ++ ) a[k] += 2 , n += 2;
}
}
}
dfs3(-1 , 100);
}
void dfs1(int p , int l)
{
if(now >= ans) return;
int i , j , k;
for(i = min(n / 3 , l) ; i >= 2 ; i -- )
{
for(j = (i == l ? p : 3) ; j <= 15 - i ; j ++ )
{
for(k = j ; k < j + i ; k ++ )
if(a[k] < 3)
break;
if(k == j + i)
{
for(k = j ; k < j + i ; k ++ ) a[k] -= 3 , n -= 3;
now ++ , dfs1(j + i , i) , now -- ;
for(k = j ; k < j + i ; k ++ ) a[k] += 3 , n += 3;
}
}
}
dfs2(-1 , 100);
}
int main()
{
int T , k;
scanf("%d%d" , &T , &k);
while(T -- )
{
int i , v , w;
n = k;
memset(a , 0 , sizeof(a));
for(i = 1 ; i <= n ; i ++ )
{
scanf("%d%d" , &v , &w);
if(!v) a[w + 14] ++ ;
else if(v == 1) a[14] ++ ;
else a[v] ++ ;
}
ans = 1 << 30 , now = 0 , dfs1(-1 , 100);
printf("%d\n" , ans);
}
return 0;
}

【bzoj4325】NOIP2015 斗地主(&“加强”版) 搜索的更多相关文章

  1. 2018.11.01 bzoj4325: NOIP2015 斗地主(贪心+搜索)

    传送门 原来一直以为是一道大模拟. 没想到是一道搜索+最优性剪枝 如何搜最优呢? 我们考虑怎么最快出完. 大概是应该尽量出当前能出出去最多的吧. 于是我们选择优先出顺子. 这样做有什么好处呢? 我们会 ...

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

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

  3. bzoj4325: NOIP2015 斗地主(爆搜+模拟)

    去年的我还不会打斗地主呵呵 觉得这道题挺难的..抄了一遍题解,感触挺多的= = 首先出牌的方式太多了不能每次都枚举所有的出牌方式, 于是分成两部分:1.顺子 2.带牌等其他 每次dfs都搜顺子,而且顺 ...

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

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

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

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

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

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

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

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

  8. NOIP2015斗地主[DFS 贪心]

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

  9. BZOJ 4325: NOIP2015 斗地主

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

  10. UOJ 151 斗地主“加强”版

    #151. [NOIP2015]斗地主“加强”版 统计 描述 提交 自定义测试 本题开放Hack 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54 ...

随机推荐

  1. WKWebView 屏蔽长按手势 - iOS

    研究半天还跟正常套路不一样,WKWebView 需要将 JS 注入进去,套路啊 ... 查半天资料,为了后者们开发可以提高效率,特此分享一下,不到的地方多多包涵哈. 废话不多说,直接上 code,将如 ...

  2. 协程实现tcp两个客户端的通讯

    import socket import gevent from gevent import monkey monkey.patch_all() def cb_work(recv_num,send_n ...

  3. spring boot+log4j2快速使用(一)

    log4j是Apache的一个开源项目,log4j2和log4j是一个作者,只不过log4j2是重新架构的一款日志组件,他抛弃了之前log4j的不足,以及吸取了优秀的logback的设计重新推出的一款 ...

  4. linux redis5.0 集群搭建

    一.下载 wget http://download.redis.io/releases/redis-5.0.0.tar.gz 二.解压.编译 #解押到 /usr/local/ 文件夹 tar -zxv ...

  5. 设置vim tab为4个空格

    Vim 编辑器默认tab为8个空格,但对于pythoner来说,必须要调整到4个空格. 方法如下: 在~/.vimrc文件中加入下面设置: set ts=4 #设置tabstop为4个空格 set e ...

  6. 【Effective C++ 读书笔记】条款02: 尽量以 const, enum, inline 替换 #define

    条款02: 尽量以 const, enum, inline 替换 #define 这个条款或许可以改为“宁可以编译器替换预处理器”. 编译过程: .c文件--预处理-->.i文件--编译--&g ...

  7. 完善压缩处理类(支持主流的图像类型(jpg、png、gif)

    <?php /* * 图像压缩 */ class Thumb { //成员属性 private $file; //原图文件 private $thumb_path; //压缩文本件保存的地址 / ...

  8. php生成微信小程序二维码源码

    目前有3个接口可以生成小程序码,开发者可以根据自己的需要选择合适的接口.第一步:获取   access_token public function getWxAccessToken(){ $appid ...

  9. php性能优化 --- laravel 性能优化

    1.laravel官方提供了一些优化(laravel 5.* 版本): (1).关闭debug,修改 .env 的  APP_DEBUG=false    (2).  sudo php artisan ...

  10. 利用python进行坐标提取以及筛选(文件操作的小应用)

    由于目前暂时还未学习到python关于数据处理的模块方面的知识,且刚好最近朋友发来一份坐标数据文件(txt格式),让我帮他对其进行筛选, 因此利用了最近刚学过的python文件处理操作以及以前所学的基 ...