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

本题数据随机,不支持hack,要hack或强力数据请点击这里
输入输出格式
输入格式:
第一行包含用空格隔开的2个正整数 T,nT,nT,n ,表示手牌的组数以及每组手牌的张数。
接下来 TTT 组数据,每组数据 nnn 行,每行一个非负整数对 ai,bia_i,b_iai,bi ,表示一张牌,其中 aia_iai 表示牌的数码, bib_ibi 表示牌的花色,中间用空格隔开。特别的,我们用 111 来表示数码 AAA, 111111 表示数码J JJ, 121212 表示数码Q QQ, 131313 表示数码 KKK;黑桃、红心、梅花、方片分别用 1−41-41−4 来表示;小王的表示方法为 010101 ,大王的表示方法为 020202 。
输出格式:
共 TTT 行,每行一个整数,表示打光第 iii 组手牌的最少次数。
输入输出样例
输入样例#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说明
共有111组手牌,包含8张牌:方片777,方片888,黑桃999,方片101010,黑桃JJJ,黑桃555,方片AAA以及黑桃AAA。可以通过打单顺子(方片777,方片888,黑桃999,方片101010,黑桃JJJ),单张牌(黑桃555)以及对子牌(黑桃AAA以及方片AAA)在333次内打光。
对于不同的测试点, 我们约定手牌组数TTT与张数nnn的规模如下:

数据保证:所有的手牌都是随机生成的。
其实只需要一个剪枝,在暴力穷举完不定长的出法之后按照从多到少的顺序枚举定长的出法,每次枚举前判断如多剩余卡牌数除以当前状态最多一次出牌数大于当前最佳答案直接\(return\)
我的第一个行数\(200+\)的代码<( ̄︶ ̄)>
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int i,m,n,j,k,a[101],t,g,h,ans=0x3f3f3f3f;
void dfs(int k,int *d,int res,int num)
{
if(num==1)
for(int i=3;i<=13;i++)
{
if((d[i]<3)||(d[i+1]<3)) continue;
d[i]-=3; res-=3;
int t=1;
while(d[i+t]>=3)
{
d[i+t]-=3;
res-=3;
dfs(k+1,d,res,1);
t+=1;
}
while(t--) d[t+i]+=3,res+=3;
}
if(num==1)
for(int i=3;i<=12;i++)
{
if((d[i]<2)||(d[i+1]<2)||(d[i+2]<2)) continue;
d[i]-=2; d[i+1]-=2; res-=4;
int t=2;
while(d[i+t]>=2)
{
d[i+t]-=2;
res-=2;
dfs(k+1,d,res,1);
t+=1;
}
while(t--) d[t+i]+=2,res+=2;
}
if(num==1)
for(int i=3;i<=10;i++)
{
if((!d[i])||(!d[i+1])||(!d[i+2])||(!d[i+3])||(!d[i+4])) continue;
d[i]-=1; d[i+1]-=1; d[i+2]-=1; d[i+3]-=1; res-=4;
int t=4;
while(d[i+t])
{
d[i+t]-=1;
res-=1;
dfs(k+1,d,res,1);
t+=1;
}
while(t--)
d[i+t]+=1,res+=1;
}
if(res/8+k>=ans) return;
for(int i=3;i<=16;i++)
{
if(d[i]<4) continue;
d[i]-=4;
res-=4;
for(int j=3;j<=16;j++)
if(d[j]>=2)
for(int l=j;l<=16;l++)
if(((j==l)&&(d[l]>=4))||((j!=l)&&(d[l]>=2)))
{
d[l]-=2; d[j]-=2; res-=4;
dfs(k+1,d,res,0);
d[l]+=2; d[j]+=2; res+=4;
}
res+=4;
d[i]+=4;
}
if(res/6+k>=ans) return;
for(int i=3;i<=16;i++)
{
if(d[i]<4) continue;
d[i]-=4; res-=4;
for(int j=3;j<=17;j++)
if(d[j])
for(int l=j;l<=17;l++)
if(((j==l)&&(d[l]>=2))||((j!=l)&&(d[l])))
{
d[l]-=1; d[j]-=1; res-=2;
dfs(k+1,d,res,0);
d[l]+=1; d[j]+=1; res+=2;
}
res+=4; d[i]+=4;
}
if(res/5+k>=ans) return;
for(int i=3;i<=16;i++)
{
if(d[i]<3) continue;
d[i]-=3; res-=3;
for(int j=3;j<=16;j++)
if(d[j]>1)
{
d[j]-=2; res-=2;
dfs(k+1,d,res,0);
d[j]+=2; res+=2;
}
res+=3; d[i]+=3;
}
if(res/4+k>=ans) return;
for(int i=3;i<=16;i++)
{
if(d[i]<3) continue;
d[i]-=3; res-=3;
for(int j=3;j<=17;j++)
if(d[j])
{
d[j]-=1; res-=1;
dfs(k+1,d,res,0);
d[j]+=1; res+=1;
}
res+=3; d[i]+=3;
}
if(res/3+k>=ans) return;
for(int i=3;i<=16;i++)
{
if(d[i]<3) continue;
d[i]-=3; res-=3;
dfs(k+1,d,res,0);
res+=3; d[i]+=3;
}
if(res/2+k>=ans) return;
for(int i=3;i<=17;i++)
{
if(d[i]<2) continue;
d[i]-=2; res-=2;
dfs(k+1,d,res,0);
res+=2; d[i]+=2;
}
ans=min(ans,k+res);
}
int main()
{
scanf("%d%d",&t,&n);
for(t;t>=1;t--)
{
memset(a,0,sizeof(a));
ans=0x3f3f3f3f;
for(i=1;i<=n;i++)
{
scanf("%d%d",&g,&h);
if(g==0) a[17]+=1;
else if(g==2) a[16]+=1;
else if(g==1) a[14]+=1;
else a[g]+=1;
}
dfs(0,a,n,1);
printf("%d\n",ans);
}
}
加强版会被hack掉一个点T到爆炸...QAQ
P2668 斗地主的更多相关文章
- 洛谷P2668 斗地主==codevs 4610 斗地主[NOIP 2015 day1 T3]
P2668 斗地主 326通过 2.6K提交 题目提供者洛谷OnlineJudge 标签搜索/枚举NOIp提高组2015 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 出现未知错误是说梗啊 ...
- Luogu P2668 斗地主(NOIP2015)
还记得那道我只用特判得了30分的"斗地主"吗? 我今天脑抽打算把它改A掉.为什么不用这大好时光去干些更有意义的事 于是我就挖了这个坑. 题解: 题目链接:P2668 斗地主 本题就 ...
- [NOIP2015] 提高组 洛谷P2668 斗地主
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...
- 洛谷P2668 斗地主 [NOIP2015]
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...
- P2668 斗地主 dp+深搜版
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...
- P2668 斗地主 贪心+深搜
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...
- 洛谷P2668斗地主(搜索)noip2015
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...
- 洛谷—— P2668 斗地主
https://www.luogu.org/problem/show?pid=2668 题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54 ...
- 洛谷P2668 斗地主
好,终于搞完了这一道毒瘤题...... 先想到搜索,然后想到状压,发现数据组数很多,又是随机,还是决定用搜索. 先搜出的多的,于是顺序是三个顺子,然后按照多到少搜带牌,最后是不带牌. 大体思路很简单, ...
随机推荐
- C#三大特性之 封装、继承、多态
一.封装: 封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类).被封装的对象通常被称为抽象数据类型. 封装的意义: 封装的意义在于保护或者防止代码(数据) ...
- nodejs记录1——async函数
其实手动配置babel环境并不难,记录下步骤: 1.首先npm init创建一个nodejs项目 2.全局安装babel-cli处理工具:npm i babel-cli -g 3.cd到项目下安装ba ...
- IniHelper——INI操作辅助类
使用INI配置文件,简单便捷. 该辅助工具类为C#操作INI文件的辅助类,源码在某位师傅的基础上完善的来,因为忘记最初的来源了,因此不能提及引用,在此深感遗憾,并对贡献者表示感谢. using Sys ...
- Python Djan 路由对应的名称
路由关系命名 对URL路由关系进行命名,以后可以根据此名称生成自己想要的URL 1. url(r'fdsafdsaeeeee',views.index, name='hello') #给这个url后面 ...
- 由上一个血案引发的关于property和attribute关系的思考
boss说,学习要刨根问底. 好的,开刨. 一.property和attribute在英语里有什么区别 看似没有区别.但其实大神说: property是 物体本身自带属性,不能改变的(一旦改了就是另外 ...
- HTML新手推荐
对于前端的学习要先了解一下浏览器和html的发展史其次看看这篇文章:https://kb.cnblogs.com/page/129756/#chapter1我读到这句话时候感觉到了科技这个东西有很多时 ...
- BZOJ2229: [Zjoi2011]最小割(最小割树)
传送门 最小割树 算法 初始时把所有点放在一个集合 从中任选两个点出来跑原图中的最小割 然后按照 \(s\) 集合与 \(t\) 集合的归属把当前集合划分成两个集合,递归处理 这样一共跑了 \(n − ...
- BZOJ4833: [Lydsy1704月赛]最小公倍佩尔数
Problem 传送门 Sol 容易得到 \[f_n=e_{n-1}+f_{n-1},e_{n-1}=f_{n-1}+e_{n-1},f_1=e_1=1\] 那么 \[f_n=2\times \sum ...
- ThreeJS模拟人沿着路径运动-路径箭头使用纹理offset偏移
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- webapi views目录下html文件无法访问
找到views下web.config 增加如下红色标注内容 <?xml version="1.0"?> <configuration> <config ...