题目描述

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

现在,牛牛只想知道,对于自己的若干组手牌,分别最少需要多少次出牌可以将它们打光。请你帮他解决这个问题。

需要注意的是,本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。

具体规则如下:

本题数据随机,不支持hack,要hack或强力数据请点击这里

输入输出格式

输入格式:

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

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

输出格式:

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

输入输出样例

输入样例#1:

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

输出样例#1:

3

输入样例#2:

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

输出样例#2:

6

说明

样例1说明

共有1组手牌,包含8张牌:方片7,方片8,黑桃9,方片10,黑桃J,黑桃5,方片A以及黑桃A。可以通过打单顺子(方片7,方片8,黑桃9,方片10,黑桃J),单张牌(黑桃5)以及对子牌(黑桃A以及方片A)在3次内打光。

对于不同的测试点, 我们约定手牌组数T与张数n的规模如下:

数据保证:所有的手牌都是随机生成的。

Solution

基本思路:

先预处理出所有不打顺子的情况,再深搜枚举顺子。

请仔细看题 注意各种细节

千万不要用平时打牌的思路做这个题目。

详情请见代码:

#include<bits/stdc++.h>
using namespace std;
int have[5],card[20],f[25][25][25][25],n,ans,kk[4]={0,5,3,2};
//f[i][j][k][w]表示有i个炸弹,j个三张一样的,k个对子和w张单牌打出的最小次数。
//kk数组是记录顺子最小长度,单牌至少5张,对子至少3个,三顺子至少2个。
void made()//这里是预处理f数组的过程.
{memset(f,63,sizeof(f));// cout<<f[1][1][1][1]<<endl;f[0][0][0][0]=1;for(int i=0;i<=n;i++)for(int j=0;j<=n;j++)for(int k=0;k<=n;k++)for(int w=0;w<=n;w++){if(4*i+3*j+2*k+w<=n){f[i][j][k][w]=i+j+k+w;//最多就是把这些不用任何带牌方法打出。if(i>0) {if(w>=2)  f[i][j][k][w]=min(f[i][j][k][w],f[i-1][j][k][w-2]+1);//这是四带两个单牌的打法。if(k>=2)  f[i][j][k][w]=min(f[i][j][k][w],f[i-1][j][k-2][w]+1);//四带两个对子的打法。f[i][j][k][w]=min(f[i][j][k][w],f[i-1][j][k][w]+1);//炸弹单独打出的打法//这是各位斗地主老司机们很容易错的地方,这里炸弹不带牌也有可能更优.
                   }if(j>0) {if(k>=1) f[i][j][k][w]=min(f[i][j][k][w],f[i][j-1][k-1][w]+1);//三带一对子。if(w>=1) f[i][j][k][w]=min(f[i][j][k][w],f[i][j-1][k][w-1]+1);//三带一张单牌。f[i][j][k][w]=min(f[i][j][k][w],f[i][j-1][k][w]+1);//三个一样的单独打出。
                   }if(k>0)   f[i][j][k][w]=min(f[i][j][k][w],f[i][j][k-1][w]+1);//打出一对子。if(w>0)   f[i][j][k][w]=min(f[i][j][k][w],f[i][j][k][w-1]+1);//打出一张单牌.
           }}return ;
}
int lemon(int a,int b,int c,int d,int king)
{if(king==0) return f[a][b][c][d];if(king==1) return f[a][b][c][d+1];//只有一张王则当单牌打出.else return min(f[a][b][c][d+2],f[a][b][c][d]+1);//两张王当两张单牌或者一起打出。//两张王不可以三带二或者四带二打出,所以是f[a][b][c][d]+1,而不是f[a][b][c+1][d];
}
void dfs(int step)
{if(step>=ans) return ;memset(have,0,sizeof(have));//记得清零数组.for(int i=2;i<=14;i++)  have[card[i]]++;ans=min(ans,step+lemon(have[4],have[3],have[2],have[1],card[0]));for(int i=1;i<=3;i++)//枚举单张顺子,对子顺子和三顺子的情况。for(int j=3;j<=14;j++)//2不能打顺子,所以从3开始。
     {int k=j;{for(k=j;k<=14&&card[k]>=i;k++)//枚举顺子的起点与终点。
          {card[k]-=i;//把顺子带出的牌减去。if(k-j+1>=kk[i]) dfs(step+1);}}k--;for(;k>=j;k--)  card[k]+=i;//把打出的顺子加回来。
     }
}
int main()
{int t,i,j;cin>>t>>n;made();//cout<<f[1][1][2][2]<<endl;for(i=1;i<=t;i++){memset(card,0,sizeof(card));for(j=1;j<=n;j++){int a;int b;cin>>a>>b;if(a==1){a=14;card[a]++;//花色不用管只要记录每个数值有多少张,1(A)是第十四个,记得特判。
          }else card[a]++;}ans=n;//给ans附一个初值。dfs(0);cout<<ans<<endl;}return 0;
}

 

转载于:https://www.cnblogs.com/Le-mon/p/7718693.html

【NOIP 2015】斗地主相关推荐

  1. NOIP 2015 蒟蒻做题记录

    昨天做了noip 2015 的题.因为之前做过几道,最开始做的很快,也都A了.可是子串斗地主运输计划什么的这些没做过的题还是把我恶心的不行QAQ我这个大蒟蒻还是没有A掉..所以说先写一下应该得到的暴力 ...

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

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

  3. NOIP 2015 D1 T2 信息传递

    趁着我还活在网上 多写点题解 * NOIP 2015 D1 T2 信息传递* 2996: [NOIP2015]信息传递 D1 T2 Time Limit: 1 Sec Memory Limit: 12 ...

  4. NOIP 2015 提高组 初赛

    NOIP 2015 提高组 初赛 疑难点 学习 感悟. 一. 3. 示例如下(来自自个的理解): 101.101 十进制 转十进制1*10^2+0*10^1+1*10^0+1*10^-1+0*10^- ...

  5. NOIP 2015 普及组 初赛

    NOIP 2015 普及组 初赛 疑难点 学习 感悟. 本份试卷本人得分93,两处错误,一错在二.1.题,眼花了,多数了个数据3241:二错在四.2.题(5)空,该空写成rbound=mid-1,这个 ...

  6. 【NOIp 2015】【DFS】斗地主

    题面 自己网上去搜吧- 代码 #include <cstdio> #include <cstring> #include <algorithm> #define I ...

  7. NOIP 2015 Day1T3 斗地主

    暴力不解释,数据随机生成,我们可以贪心的按打出牌的数量从多到少出,那么这样就能够使最优化剪枝起到很重要的作用,怎样简化代码呢?我从题解中发现了一种将单顺子,双顺子和三顺子合成一种的方法,具体实现看代码 ...

  8. NOIP 2015 简记

    Day 0 12点上车,坐在准备出发的车子上和一群同学打招呼,真是逗.. 由于1个同学忘带身份证,强行拖到1点钟才发车,RP这么差肯定要跪. 路上一群同学在玩关灯游戏,一想是POJ 1222,就顺手写 ...

  9. UOJ #149 [NOIP 2015] 子串

    传送门 Solution DP+滚动数组. DP状态 $dp[i][j][k]$: $A$的第$i$个字符和$B$的第$j$个字符匹配且该字符在第$k$个子串中的方案数. 转移方程 $dp[0][0] ...

最新文章

  1. Linux系统的快照是什么,linux – 文件系统快照与简单复制文件有何不同?
  2. vue中create 什么触发_vue中eventbus被多次触发(vue中使用eventbus踩过的坑)
  3. 第十六章:Java内存模型——Java并发编程实战
  4. Linux中点号,星号,加号,问号实战
  5. 几种软件滤波算法的原理和比较(带源码)
  6. oa处理会签流程图_简易OA漫谈之工作流设计(四,怎么支持会签)
  7. javascript设置首页,加入收藏
  8. conda安装与入门
  9. 书籍推荐系列之一 -- 《凤凰项目:一个IT运维的传奇故事》
  10. 我的2016--远方不一定有诗,但有更好的自己
  11. Google Authenticator(谷歌身份验证器)C#版
  12. Swarm and shipyard
  13. java程序调用百度Geocoding API逆地址解析通过经纬度查询位置
  14. 【Codecs系列】双帧参考特性
  15. 19.调整数组奇偶数
  16. 熊向阳:PR更新以及提高PR的必要因素
  17. Jetson Nano B01 无界面初始化安装系统+飞桨(Paddle)v2.0
  18. 欧洲6G时间表、目标和关键技术(下篇)
  19. 创意黑板教育教学PPT模板
  20. 人工智能期末复习4.专家系统

热门文章

  1. Perl面向对象编程入门
  2. 《被讨厌的勇气》书摘心得之一切烦恼都来自人际关系(2)
  3. CISCO2600路由器入门3
  4. 测试过程中遇到的问题总结
  5. app播放无声音乐实现app后台运行
  6. STM32常见通信方式(TTL、RS232、RS485、I2C,SPI,CAN)总结
  7. 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标
  8. 适合练习听力的英文电影推荐
  9. 用angular JS和 bootstrap完成一个简单的购物车界面
  10. 【DRF+Django】微信小程序入门到实战_day04(上)