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,记录下来每个权值的边使用的数量(可以离散化一下) 可以证明,对于每个权值,所有的最小生成树中选择的数量是一样的.而且它们连成 ...
随机推荐
- 02 Vue介绍与安装,指令系统 v-*、音乐播放器
VUE文档 https://cn.vuejs.org/v2/guide/ 1.vue的介绍 尤雨溪 1.vue的优点 2.vue的介绍 3.vue的安装 4.声明式渲染 <body> &l ...
- hdu 6070 Dirt Ratio
题 OvO http://acm.hdu.edu.cn/showproblem.php?pid=6070 (2017 Multi-University Training Contest - Team ...
- Java File download
注意文件响应处理方式,是响应为网页形式还是附件显示,看如下信息: In a regular HTTP response, the Content-Disposition response ...
- windows 控制台 命令行指令换行
由于屏幕较小而指令太长,在书写的时候不好阅读. 其实cmd和Linux一样可以通过特殊符号换行的: Linux 为 \ 而cmd 为 ^ 看图 这就很美观了,拯救了我的强迫症 ^_^ ...
- html基础(选择器,font属性 )
css选择器 css与html的关系 css以html为基础 css主要设置的就是html标签中的属性样式,css进行网页布局. css语法 选择器{属性:值,属性:值} css选择 ...
- 「前端」尚妆 UI 组件库工程实践(weex vue)
本文来自尚妆前端团队南洋 发表于尚妆github博客,欢迎订阅! 前言 尚妆大前端团队使用 weex 进行三端统一开发有一段时间了,截止本文发表「达人店」APP大部分页面都已经用 weex 进行了重构 ...
- redis远程连接命令
redis-cli -h 172.17.0.85 -p 6379 输入密码 auth "1234
- 遍历 ArrayList与Map集合
import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * 遍历 ArrayList * @ ...
- anaconda环境管理
创建新环境 conda create -n rcnn python=3.6 删除环境 conda remove -n rcnn --all 重命名环境 参考SO:https://stackoverfl ...
- HBuilder开发MUI web app溢出页面上下无法滚动问题
因为没有对页面初始化,所以页面溢出部分不会显示,要解决此问题需要加上下面代码: JS代码: (function($){$(".mui-scroll-wrapper").scroll ...