题解 P2668 【斗地主】
dfs+简易剪枝+简易a*
思路:
dfs+简易剪枝+简易a(我也不知道算不算a);
dfs参数记录层数
按消耗牌多少的贪心顺序搜索
有几种情况可以不用搜索(但我还是搜索了)
可以用a*估算出来
最后剩下有单牌,对子,三张牌,4炸弹的时候可以直接算出来;
还有一个剪枝,一个简简单单的剪枝(if(x>=ans) return;);
这个因为省略了很多情况所以并不很慢;
反正我是过了;
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,jk,kl,ai,bi,hand[],ans=0x7fffffff;
int t,c[];
int A_star() {
memset(c,,sizeof(c));
int tot=,kll=;
for(int i=; i<=; i++) c[hand[i]]++; //统计当前还剩的牌数
while(c[]&&c[]>) c[]--,c[]-=,tot++;//四带一对
while(c[]&&c[]>) c[]--,c[]-=,tot++;//四带两单
while(c[]&&c[]) c[]--,c[]--,tot++;//三带二
while(c[]&&c[]) c[]--,c[]--,tot++;//三带一
for(int i=; i<=; i++) kll+=c[i];
return tot+kll;//带牌+三张 对子 单张
}
void dfs(int x) {
// num=min(num,ans);
// printf("%d %d ",x,ans);
// for(int i=1;i<=15;i++) printf("%d ",hand[i]);
// printf("\n");
if(x>=ans) return;
int pd=;
int cur=; for(int i=; i<=; i++) { //四带两对
if(hand[i]>=) {
hand[i]-=;
for(int j=; j<=; j++) {
if(j!=i&&hand[j]>=) {
hand[j]-=;
for(int v=; v<=; v++) {
if(hand[v]>=&&v!=j) {
hand[v]-=;
// printf("1 ");
dfs(x+);
hand[v]+=;
}
}
hand[j]+=;
}
}
hand[i]+=;
}
}
for(int i=; i<=; i++) { //四带二单
if(hand[i]>=) {
hand[i]-=;
for(int j=; j<=; j++) {
if(j!=i&&hand[j]>=) {
hand[j]-=;
for(int v=; v<=; v++) {
if(hand[v]>=&&v!=i) {
hand[v]-=;
/// printf("2 ");
dfs(x+);
hand[v]+=;
}
}
hand[j]+=;
}
}
hand[i]+=;
}
}
for(int i=; i<=; i++) { //三顺
cur=;
if(hand[i]>=&&i<=) {
for(int j=i; j<=; j++) {
if(hand[j]>=) cur++;
else break;
}
for(int j=cur; j>=; j--) {
for(int v=i; v<=j+i-; v++) hand[v]-=;
// printf("3 ");
dfs(x+);
for(int v=i; v<=j+i-; v++) hand[v]+=;
}
}
}
for(int i=; i<=; i++) { //二顺
cur=;
if(hand[i]>=&&i<=) {
for(int j=i; j<=; j++) {
if(hand[j]>=) cur++;
else break;
}
for(int j=cur; j>=; j--) {
for(int v=i; v<=j+i-; v++) hand[v]-=;
// printf("4 ");
dfs(x+);
for(int v=i; v<=j+i-; v++) hand[v]+=;
}
}
}
for(int i=; i<=; i++) { //一顺
cur=;
if(hand[i]>=&&i<=) {
for(int j=i; j<=; j++) {
if(hand[j]>=) cur++;
else break;
}
for(int j=cur; j>=; j--) {
for(int v=i; v<=j+i-; v++) hand[v]-=;
// printf("5 ");
dfs(x+);
for(int v=i; v<=j+i-; v++) hand[v]+=;
}
}
}
for(int i=; i<=; i++) { //三带二
if(hand[i]>=) {
hand[i]-=;
for(int j=; j<=; j++) {
if(j!=i&&hand[j]>=) {
hand[j]-=;
// printf("6 ");
dfs(x+);
hand[j]+=;
}
}
hand[i]+=;
}
}
for(int i=; i<=; i++) { //三带一
if(hand[i]>=) {
hand[i]-=;
for(int j=; j<=; j++) {
if(j!=i&&hand[j]>=) {
hand[j]-=;
// printf("7 ");
dfs(x+);
hand[j]+=;
}
}
hand[i]+=;
}
}
if(hand[]>=&&hand[]>=) {
hand[]--;
hand[]--;
// printf("8 ");
dfs(x+);
hand[]++;
hand[]++;
}
jk=A_star();
if(x+jk>=ans) return;
else ans=x+jk;
} int main() {
scanf("%d%d",&t,&n);
while(t--) {
memset(hand,,sizeof(hand));
ans=0x7fffffff;
for(int i=; i<=n; i++) {
cin>>ai>>bi;
if(ai!=) {
if(ai>=) hand[ai-]++;
else hand[+ai]++;
} else {
if(bi==) hand[]++;
else hand[]++;
}
}
// for(int i=1;i<=15;i++) printf("%d ",hand[i]);
// printf("\n");
dfs();
printf("%d\n",ans);
}
return ;
}
斗地主,感觉写完这个代码我都成了斗地主大神了。
题解 P2668 【斗地主】的更多相关文章
- 洛谷P2668 斗地主==codevs 4610 斗地主[NOIP 2015 day1 T3]
P2668 斗地主 326通过 2.6K提交 题目提供者洛谷OnlineJudge 标签搜索/枚举NOIp提高组2015 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 出现未知错误是说梗啊 ...
- Luogu P2668 斗地主(NOIP2015)
还记得那道我只用特判得了30分的"斗地主"吗? 我今天脑抽打算把它改A掉.为什么不用这大好时光去干些更有意义的事 于是我就挖了这个坑. 题解: 题目链接:P2668 斗地主 本题就 ...
- 洛谷P2668 斗地主 [NOIP2015]
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...
- [NOIP2015] 提高组 洛谷P2668 斗地主
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...
- P2668 斗地主
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的AAA到KKK加上大小王的共545454张牌来进行的扑克牌游戏.在斗地主中,牌的大小关 系根据牌的数码表示如下: ...
- 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 ...
随机推荐
- Java文件上传的几种方式
文件上传与文件上传一样重要.在Java中,要实现文件上传,可以有两种方式: 1.通过Servlet类上传 2.通过Struts框架实现上传 这两种方式的根本还是通过Servlet进行IO流的操作. 一 ...
- win10 mysql5.7.28 配置安装
如果有服务,使用下面命令删除,管理员身份打开cmd : sc delete mysql 1.下载 https://dev.mysql.com/downloads/mysql/5.7.html 没有的O ...
- ThinkPHP 3.2 自定义基类 Model
ThinkPHP 提供了一个 Model 类,供其他的 Model 进行继承.Model 类中是 MVC 中的模型类,它是调用 持久层 的上层类.感觉这么描述问题很多,但是有什么办法呢?但是,这个 M ...
- sierpinski地毯(II)
今天又是因为可以用py而高兴的一天. 继续咱的sierpinski地毯计划. 二,随机算法 在二十年前,磁盘容量以MB还是KB计的时候,分形解决计图的问题确实有很大的优势.存至多十来个数就好了.我要在 ...
- redis延迟队列
异步消息队列 Redis 的 list(列表) 数据结构常用来作为异步消息队列使用,使用rpush/lpush操作入队列, 使用 lpop 和 rpop 来出队列. > rpush notify ...
- python 自定义Iterator对象
from collections.abc import Iterator class Company(object): def __init__(self, employee_list): self. ...
- DAX 第七篇:分组聚合
DAX有三个用于生成分组聚合数据的函数,这三个函数有两个共同的特征:分组列和扩展列. 分组列是用于分组的列,只能来源于基础表中已存的列,分组列可以来源于同一个表,也可以来源于相关的列. 扩展列是由na ...
- WebApplicationInitializer启动分析
从Servlet 3.0 开始Tomcat已经支持注解式的配置.了解下,在注解的配置方式下,Web是怎样启动起来的. 通过注解配置一个Web应用 下面是一个通过注解实现一个简单的Web应用 publi ...
- SqlServer 开篇简介
实例:我们的电脑中可以安装一个或多个SqlServer实例,每一个SqlServer实例可以包含一个或者多个数据库. 架构:数据库中,又有一个或者多个架构.架构里面包含:表,视图,存储过程. 文件与文 ...
- Java内功心法,深入解析面向对象
什么是对象 对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位.一个对象由一组属性和对这组属性进行操作的一组服务组成. 类的实例化可生成对象,一个对象的生命周期包括三个阶段:生成.使用 ...