NOIp2015D1T3 斗地主【暴搜】
刚开始读到题目的时候,非常懵逼,非常崩溃,写着写着呢,也有点崩溃,细节有点多。
这个做法呢,只能过掉官方数据,洛谷上好像有加强版,只能得$86$分,就没有管了。
大概说一下思路:
暴力搜索每一种可能的情况,如果可以就递归下去,然后回溯。
搜索框架的话,大概就是把当前搜到的出牌次数传到参数里面,如果参数已经大于了当前的最小答案就剪枝退出。然后在当前状态下枚举每一种出牌的情况,能够出就出,然后递归到下一层,参数出牌次数+1。
可以证明不会无限递归下去,因为在参数已经大于了当前的最小答案的时候就退出了。
可以分为三大类出牌:顺子、带牌、散牌
还有一些细节什么的:
1.把$A$放在$K$后面,顺子的时候比较方便
2.$2$不能在顺子里面(当时还理解了好久$2$点是什么,还以为是什么其他代称...)
3.王。之前以为王只可以单出或者火箭,没有认真读题,王是可以被带的,但是只能带单牌,王不能看成一对,他们牌值不一样。
4.后来发现顺子和带牌打完之后,可以不用单独考虑打散牌(单牌,对子,三张牌),因为如果剩下,$1$次就可以打出去一种,而且无论如何只打$1$次用的打牌次数会最少。而且散牌不用考虑与其他牌的组合。(可以感性理解,次数最多肯定是每一次都按种数打散牌)
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define N 30
int rd()
{
int f=,s=;char c=getchar();
while(c<''||c>''){if(c=='-') f=-;c=getchar();}
while(c>=''&&c<=''){s=(s<<)+(s<<)+(c^);c=getchar();}
return f*s;
}
//J->11 Q->12 K->13 A->14 2->15 King->16
//王特殊处理 只能出火箭或者单出(糟糕 还可以单带
//2不能出顺子
int n,ans;
int cnt[N];
void dfs(int res)
{
if(res>=ans) return ;//剪枝 提前退出
/*
//-----炸弹
for(int i=3;i<=15;i++)
if(cnt[i]>=4)
{
cnt[i]-=4;
dfs(res+1);
cnt[i]+=4;
}
//-----
//-----对子牌
for(int i=3;i<=15;i++)
if(cnt[i]>=2)
{//2个对子...就是炸弹了 应该在前面判断过了
cnt[i]-=2;
dfs(res+1);
cnt[i]+=2;
}
//-----
//-----三张牌
for(int i=3;i<=15;i++)
if(cnt[i]>=3)
{
cnt[i]-=3;
dfs(res+1);
cnt[i]+=3;
}
//-----
*/
//-----顺子
//---单顺子
int k=;
for(int i=;i<=;i++)//不包括2点
{
if(cnt[i]==) k=;//顺子断了 从这里重新开始
else//否则就接下去
{
k++;
if(k>=)
{
for(int j=i;j>=i-k+;j--)
cnt[j]--;
dfs(res+);
for(int j=i;j>=i-k+;j--)
cnt[j]++;
}
}
}
//---
//---双顺子
k=;
for(int i=;i<=;i++)//不包括2点
{
if(cnt[i]<) k=;//顺子断了 从这里重新开始
else//否则就接下去
{
k++;
if(k>=)
{
for(int j=i;j>=i-k+;j--)
cnt[j]-=;
dfs(res+);
for(int j=i;j>=i-k+;j--)
cnt[j]+=;
}
}
}
//---
//---三顺子
k=;
for(int i=;i<=;i++)//不包括2点
{
if(cnt[i]<) k=;//顺子断了 从这里重新开始
else//否则就接下去
{
k++;
if(k>=)
{
for(int j=i;j>=i-k+;j--)
cnt[j]-=;
dfs(res+);
for(int j=i;j>=i-k+;j--)
cnt[j]+=;
}
}
}
//---
//-----
//-----带牌
for(int i=;i<=;i++)
{
if(cnt[i]<) continue;
//3带X
cnt[i]-=;
for(int j=;j<=;j++)
{
if(i==j) continue;
if(cnt[j]>=)
{
cnt[j]--;
dfs(res+);
cnt[j]++;
}
if(cnt[j]>=&&j!=/*王不能一起带*/)
{
cnt[j]-=;
dfs(res+);
cnt[j]+=;
}
}
cnt[i]+=;
//4带X(两个单张或两个对)
if(cnt[i]<) continue;
cnt[i]-=;
for(int j=;j<=;j++)
{
if(i==j||cnt[j]<=) continue;
cnt[j]--;//两张单牌
for(int k=;k<=;k++)
{
if(k==j||k==i||cnt[k]<) continue;
cnt[k]--;
dfs(res+);
cnt[k]++;
}
cnt[j]++;
if(cnt[j]<||j==/*王不能一起*/) continue;
cnt[j]-=;//两对对子
for(int k=;k<=;k++)
{
if(k==j||k==i||cnt[k]<) continue;
cnt[k]-=;
dfs(res+);
cnt[k]+=;
}
cnt[j]+=;
}
cnt[i]+=;
}
//-----
for(int i=;i<=;i++)
if(cnt[i]) res++;
//突然发现 单张 对子三张都不用特殊考虑 反正能一次出完剩下的所有牌
ans=min(ans,res);
}
int main()
{
int T=rd(),n=rd();
while(T--)
{
memset(cnt,,sizeof(cnt));
ans=INF;
for(int i=;i<=n;i++)
{
int m=rd(),opt=rd();
if(m==) m=;
if(m==) m=;
if(m==) m=;
cnt[m]++;
}
dfs();
printf("%d\n",ans);
}
return ;
}
Code
NOIp2015D1T3 斗地主【暴搜】的更多相关文章
- 【BZOJ-3033】太鼓达人 欧拉图 + 暴搜
3033: 太鼓达人 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 204 Solved: 154[Submit][Status][Discuss] ...
- c++20701除法(刘汝佳1、2册第七章,暴搜解决)
20701除法 难度级别: B: 编程语言:不限:运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 输入正整数n,按从小到大的顺序输出所有 ...
- Codeforces Round #238 (Div. 2) D. Toy Sum 暴搜
题目链接: 题目 D. Toy Sum time limit per test:1 second memory limit per test:256 megabytes 问题描述 Little Chr ...
- poj 3080 Blue Jeans(水题 暴搜)
题目:http://poj.org/problem?id=3080 水题,暴搜 #include <iostream> #include<cstdio> #include< ...
- Sicily1317-Sudoku-位运算暴搜
最终代码地址:https://github.com/laiy/Datastructure-Algorithm/blob/master/sicily/1317.c 这题博主刷了1天,不是为了做出来,AC ...
- codeforces 339C Xenia and Weights(dp或暴搜)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Xenia and Weights Xenia has a set of weig ...
- Usaco 2.3 Zero Sums(回溯DFS)--暴搜
Zero SumConsider the sequence of digits from 1 through N (where N=9) in increasing order: 1 2 3 ... ...
- HDU4403(暴搜)
A very hard Aoshu problem Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & ...
- suoi62 网友跳 (暴搜+dp)
传送门 sbw太神啦orz 首先N<=20可以直接暴搜 然后玄学剪枝可以过18个点 那么N<=40的时候,就把它拆成两半分别暴搜,再用dp拼起来 对于前半段,设f[i][j]是开始高度为i ...
- bzoj1016/luogu4208 最小生成树计数 (kruskal+暴搜)
由于有相同权值的边不超过10条的限制,所以可以暴搜 先做一遍kruskal,记录下来每个权值的边使用的数量(可以离散化一下) 可以证明,对于每个权值,所有的最小生成树中选择的数量是一样的.而且它们连成 ...
随机推荐
- isset和empty以及is_null区别
2.empty,isset首先都会检查变量是否存在,然后对变量值进行检测.而is_null 和 “参数本身”只是直接检查变量值,是否为null,因此如果变量未定义就会出现错误! 3.isset():仅 ...
- 前端Web浏览器基于Flash如何实时播放监控视频画面(四)之使用videoJs‘拉流’
本片文章只是起到抛砖引玉的作用,能从头到尾走通就行,并不做深入研究.为了让文章通俗易懂,尽量使用白话描述. 0x001: 下载videoJs 对于Video.js 5.x及更低版本,Flash技术(v ...
- codevs3269 混合背包 x
3269 混合背包 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 背包体积为V ,给出N个物品,每个物品占用体积为 ...
- Python和Sublime的整合
按照下面的方式也可以运行py代码,但是交互方式不是很好,主要简单介绍了一下Python和Sublime的整合 一 Ctrl + B 二 SublimeREPL 安装SublimeREPL 1.打开P ...
- 灰度图像--图像增强 Robert算子、Sobel算子
学习DIP第36天 转载请标明本文出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些论坛转载后,图像无法正常显示,无法正常表达本人观点,对此表示很不 ...
- 基于node、webpack、搭建一个koa服务器
1.首先需要node(去官网下载) 2.见一个文件夹 比如koa cmd——r cd koa文件 3.npm init 4.安装webpack (本地安装 ...
- Node.js 安装与开发
Node.js 简介 Node.js是一个Javascript运行环境(runtime),发布于2009年5月,由Ryan Dahl开发,实质是对Chrome V8引擎进行了封装.Node.js对一些 ...
- Jmeter(十二)常用插件
一.下载及安装 下载地址:https://jmeter-plugins.org/install/Install/ 下载后文件为一个jar包,将其放入jmeter安装目录下的lib/ext目录,然后重启 ...
- DB 分库分表(2):全局主键生成策略
DB 分库分表(2):全局主键生成策略 本文将主要介绍一些常见的全局主键生成策略,然后重点介绍flickr使用的一种非常优秀的全局主键生成方案.关于分库分表(sharding)的拆分策略和实施细则,请 ...
- JAVA开发框架
1.Bootstrap Bootstrap是美国Twitter公司的设计师Mark Otto和Jacob Thornton合作基于HTML.CSS.JavaScript 开发的简洁.直观.强悍 ...