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

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

  嗯,不剪枝也飞快的。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 const int N=15;
 6 int cnt[N];
 7 int DFS(int d=0){
 8   int flag=0,ret=100;
 9   for(int i=0;i<=14;i++)
10     if(cnt[i])flag=1;
11   if(!flag)return 0;
12   for(int i=3;i<=10;i++){
13     flag=1;
14     for(int j=i;j<=i+3;j++)if(!cnt[j])flag=0;
15     if(!flag)continue;
16     for(int j=i;j<=i+3;j++)cnt[j]-=1;
17     for(int j=i+4;j<=15;j++){
18       if(cnt[j]){cnt[j]-=1;ret=min(ret,DFS()+1);}
19       else{for(int k=j-1;k>=i;k--)cnt[k]+=1;break;}
20     }
21   }
22
23   for(int i=3;i<=12;i++){
24     flag=1;
25     for(int j=i;j<=i+1;j++)if(cnt[j]<2)flag=0;
26     if(!flag)continue;
27     for(int j=i;j<=i+1;j++)cnt[j]-=2;
28     for(int j=i+2;j<=15;j++){
29       if(cnt[j]>=2){cnt[j]-=2;ret=min(ret,DFS()+1);}
30       else{for(int k=j-1;k>=i;k--)cnt[k]+=2;break;}
31     }
32   }
33
34   for(int i=3;i<=13;i++){
35     flag=1;
36     for(int j=i;j<=i;j++)if(cnt[j]<3)flag=0;
37     if(!flag)continue;
38     for(int j=i;j<=i;j++)cnt[j]-=3;
39     for(int j=i+1;j<=15;j++){
40       if(cnt[j]>=3){cnt[j]-=3;ret=min(ret,DFS()+1);}
41       else{for(int k=j-1;k>=i;k--)cnt[k]+=3;break;}
42     }
43   }
44
45   //三带一 三带二
46   for(int i=0;i<=14;i++){
47     if(cnt[i]<3)continue;
48     cnt[i]-=3;
49     for(int j=1;j<=14;j++){
50       if(i==j)continue;
51       if(cnt[j]>=2){cnt[j]-=2;ret=min(ret,DFS()+1);cnt[j]+=2;}
52       if(cnt[j]){cnt[j]-=1;ret=min(ret,DFS()+1);cnt[j]+=1;}
53     }
54     cnt[i]+=3;
55   }
56
57   for(int i=0;i<=14;i++){
58     if(cnt[i]<4)continue;
59     cnt[i]-=4;
60     for(int j=1;j<=14;j++)if(i!=j&&cnt[j]>1)
61     for(int k=j+1;k<=14;k++)if(i!=k&&cnt[k]>1)
62       {cnt[j]-=2;cnt[k]-=2;ret=min(ret,DFS()+1);cnt[j]+=2;cnt[k]+=2;}
63
64     for(int j=1;j<=14;j++)if(i!=j&&cnt[j])
65     for(int k=j+1;k<=14;k++)if(i!=k&&cnt[k])
66       {cnt[j]-=1;cnt[k]-=1;ret=min(ret,DFS()+1);cnt[j]+=1;cnt[k]+=1;}
67     cnt[i]+=4;
68   }
69   flag=0;
70   for(int i=0;i<=14;i++)if(cnt[i])flag+=1;
71   return min(ret,flag);
72 }
73 int T,n;
74 int main(){
75     //freopen("landlords.in","r",stdin);
76     //freopen("landlords.out","w",stdout);
77   scanf("%d%d",&T,&n);
78   while(T--){
79     memset(cnt,0,sizeof(cnt));
80     for(int i=1,a,b;i<=n;i++){
81       scanf("%d%d",&a,&b);
82       cnt[a]+=1;
83     }
84     cnt[14]=cnt[1];cnt[1]=0;
85     printf("%d\n",DFS(1));
86   }
87   return 0;
88 }
时间: 2024-10-17 12:57:46

基础算法(搜索):NOIP 2015 斗地主的相关文章

[NOIp 2015]斗地主

Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,而花色并不对牌的大小产生影响.每一局游戏中,一副手牌由n张牌组成.游戏者每次可以根据规定的牌型进行出牌,首先打光自己的手牌一方取得游戏的胜利.现在,牛牛只想知道,对

[BZOJ 4325][NOIP 2015] 斗地主

一道防AK好题 4325: NOIP2015 斗地主 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 820  Solved: 560[Submit][Status][Discuss] Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10&l

算法与数据结构基础 - 广度优先搜索(BFS)

BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数据结构基础 - 队列(Queue) 最直观的BFS应用是图和树的遍历,其中图常用邻接表或矩阵表示,例如 LeetCode题目 690. Employee Importance: // LeetCode 690. Employee Importance/* class Employee { publi

九章算法 基础算法 强化算法 系统设计 大数据 安卓 leetcode 高清视频

leetcode 直播视频讲座录像 九章算法视频录像,PPT 算法班,算法强化班,Java入门与基础算法班,big data项目实战班,Andriod项目实战班 九章算法下载 九章算法面试 九章算法leetcode 九章算法答案 九章算法mitbbs 九章算法班 九章算法ppt 九章算法录像 九章算法培训 九章算法微博 leetcode 视频 九章算法偷录 算法培训 算法班课程大纲: 1 从strStr谈面试技巧与Coding Style(免费试听) 2 二分搜索与旋转排序数组 Binary S

证券投资基金基础知识考试大纲(2015年度)

证券投资基金基础知识考试大纲(2015年度) 导读: 证券投资基金基础知识考试大纲(2015年度)已公布,考试大纲自2015年7月16日通知发布之日起开始实施. 基金从业资格全国统一考试大纲——证券投资基金基础知识(2015年度) 一.总体目标 为确保基金从业人员掌握与了解基金行业相关的基本知识与专业技能,具备从业必须的执业能力,特设<证券投资基金基础知识>科目. 报名动态:2016年基金从业资格考试时间 |2016年基金从业资格考试报名时间 二.能力等级 能力等级是对考生专业知识掌握程度的最

基础算法之排序--快速排序

1 /************************************************************************************** 2 * Function : 快速排序 3 * Create Date : 2014/04/21 4 * Author : NTSK13 5 * Email : [email protected] 6 * Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性. 7 * 任何单位和个人不经本人允许不

算法录 之 基础算法

这一篇文章主要说说一些基础算法,这些算是很多其他算法的基石. 主要包括  模拟,暴力,枚举,递归,贪心,分治. 1,模拟: 顾名思义,模拟就是...饿,模拟,有一些题目就是给你一些步骤,然后你写代码一步步去模拟那些步骤就行.这类题目主要属于基础题,但是当然如果需要模拟的步骤足够恶心的话,还是比较麻烦的... 具体模拟的例子在之后的练习中会遇到的,按照题目要求一步步做就行,一般算法难度比较小. 2,暴力: 顾名思义,暴力就是...饿,暴力.比如说题目让从平面上的10个点中取三个点,让他们形成的三角

[ jquery 过滤器 nextUntil([exp|ele][,fil]) ] 此方法用于在选择器的基础之上搜索被选元素的后面的所有同级元素,方法返回 selector 与 stop 之间的每个元素之后的所有同级元素,并且提供第二个参数来用于实现过滤效果,多个参数使用逗号相隔

此方法用于在选择器的基础之上搜索被选元素的后面的所有同级元素,方法返回 selector 与 stop 之间的每个元素之后的所有同级元素,并且提供第二个参数来用于实现过滤效果,多个参数使用逗号相隔,参数解释如下: 概述: 查找当前元素之后所有的同辈元素,直到遇到匹配的那个元素为止. 如果提供的jQuery代表了一组DOM元素,.nextUntil()方法也能让我们找遍所有元素所在的DOM树,直到遇到了一个跟提供的参数匹配的元素的时候才会停下来.这个新jQuery对象里包含了下面所有找到的同辈元素

[ jquery 过滤器 offsetParent() ] 此方法用于在选择器的基础之上搜索被选元素有定位的父级元素,仅对可见元素有效

此方法用于在选择器的基础之上搜索被选元素有定位的父级元素,仅对可见元素有效: 返回第一个匹配元素用于定位的父节点,这返回父元素中第一个其position设为relative或者absolute的元素,此方法仅对可见元素有效 实例: <html lang='zh-cn'> <head> <title>Insert you title</title> <meta http-equiv='description' content='this is my pa