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 斗地主
好,终于搞完了这一道毒瘤题...... 先想到搜索,然后想到状压,发现数据组数很多,又是随机,还是决定用搜索. 先搜出的多的,于是顺序是三个顺子,然后按照多到少搜带牌,最后是不带牌. 大体思路很简单, ...
随机推荐
- DQ8通关攻略
<勇者斗恶龙8>作为勇者斗恶龙系列首次实现3D的一作,游戏无论是从画面.音效还是游戏系统都表现非常不俗,这款游戏也是PS2主机上必玩的一款大作. 作为PS2平台上唯一一款勇者斗恶龙的正传新 ...
- jQuery——随笔
jQuery——随笔 jQuery的parseInt方法 在使用parseInt方法的时候要注意解析失败的问题,解析失败返回的是NaN 计算sum=sum+parseInt(num);的时候可以报错, ...
- Java - 慎用tagged class
作者的原标题是<Prefer class hierarchies to tagged classes>,即用类层次优于tagged class. 我不知道有没有tagged class这么 ...
- 基于标注的AOP面向切面编程
1.什么是AOP Aspect Orientied Programming的简称,即 面向(方面)切面编程 ,不改变一个组件源代码的情况下 可以对组件功能进行增强. 例如:servlet中的过滤 ...
- Max Sum(经典DP)
求最长总和序列,状态转移方程:dp[i] = max(dp[i-1]+a[i].a[i]) 因为可能有负数,所以要判断dp是否大于0,如果小于0则序列中断,从中断点开始 起始点可以用数组s保存,有中断 ...
- springboot开篇 (一)简单邮件发送
上篇终结篇为spring 发送邮件,这次将使用springboot 发送邮件,同时本篇将作为springboot入门篇. 新建一个工程..工程目录结构如下,此次使用idea进行开发.对于一个长期使用e ...
- webpack执行过程
webpack-cli 执行过程 1.webpack.config.js,shell options参数解析 2.new webpack(options) 3.run() 编译的入口方法 4.comp ...
- MyEclipse中设置开发项目时使用的默认JDK
安装好MyEclipse之后,在MyEclipse中开发项目时,默认使用的是MyEclipse是自带的JDK,如下图所示: 如果我们需要使用自己安装好的JDK,那么就需要在MyEclipse中重新设置 ...
- react 共享数据流
层层传递Props 单向数据流层层传递,繁琐不好管理. Context 什么是context? context是react提供的组件通信api context有什么用? 解决{组件.js}中多层级组件 ...
- redhat系统下三种主要的软件包安装方法
1. 通过RPM软件包来安装 RPM(Redhat Package Management)标准的软件包,只需简单地输入命令“rpm -ivh filename.rpm”即可: 如果需要对已经安装的RP ...