NOIP 2014【斗地主】
这真是道大火题。
因为保证数据随机,所以开始很多人直接用搜索 + 贪心水过去了,后来,为了遏制骗分这种不良风气的传播,各大 OJ 相继推出了斗地主加强版……
正解:
先爆搜顺子,枚举打或不打,打多少张。对于剩下的散牌做 DP,最少需要多少次打完。
设 \(f[i][j][k][l]\) 表示四张牌的剩 \(i\) 张,三张牌的剩 \(j\) 张,两张牌的剩 \(k\) 张,一张牌的剩 \(l\) 张,最少需要多少次打完。因为不考虑打顺子,所以点数与打完的次数无关。然后按照题目除顺子之外的打法转移即可。
与加强版的区别就是网能不能看成普通对子。
注意
记忆化搜索的值莫名其妙的变化了多半是数组越界。
搜索不要没想清楚就随便剪枝,可能不知不觉中就剪挂了。
代码是加强版的。
#include <bits/stdc++.h>
using namespace std;
#define N 25
#define RG register
inline int gi()
{
	RG int ret; RG char ch;
	ret=0, ch=getchar();
	while (ch < '0' || ch > '9')
		ch=getchar();
	while (ch >= '0' && ch <= '9')
		ret=(ret<<3)+(ret<<1)+ch-'0', ch=getchar();
	return ret;
}
int tong[N],f[N][N][N][N];
int ans,n;
inline int cal(int i,int j,int k,int l)
{
	if (f[i][j][k][l] || (!i && !j && !k && !l))
		return f[i][j][k][l];
	RG int ret;
	ret=i+j+k+l;
	if (i)
		ret=min(ret,min(cal(i-1,j+1,k,l+1),cal(i-1,j,k+2,l)));
	if (j)
		ret=min(ret,cal(i,j-1,k+1,l+1));
	if (k)
		ret=min(ret,cal(i,j,k-1,l+2));
	if (i && k > 1)
		ret=min(ret,cal(i-1,j,k-2,l)+1);
	if (i && l > 1)
		ret=min(ret,cal(i-1,j,k,l-2)+1);
	if (j && k)
		ret=min(ret,cal(i,j-1,k-1,l)+1);
	if (j && l)
		ret=min(ret,cal(i,j-1,k,l-1)+1);
	return f[i][j][k][l]=ret;
}
inline void dfs(int dep)
{
	if (dep >= ans)
		return;
	RG int i,j,k,l,tot;
	for (i=3; i<11; ++i)
		{
			if (!tong[i])
				continue;
			tot=1, j=i+1;
			while (tong[j])
				tot++, j++;
			if (tot < 5)
				continue;
			for (j=5; j<=tot; ++j)
				{
					for (k=0; k<j; ++k)
						tong[i+k]--;
					dfs(dep+1);
					for (k=0; k<j; ++k)
						tong[i+k]++;
				}
		}
	for (i=3; i<13; ++i)
		{
			if (tong[i] < 2)
				continue;
			tot=1, j=i+1;
			while (tong[j] >= 2)
				tot++, j++;
			if (tot < 3)
				continue;
			for (j=3; j<=tot; ++j)
				{
					for (k=0; k<j; ++k)
						tong[i+k]-=2;
					dfs(dep+1);
					for (k=0; k<j; ++k)
						tong[i+k]+=2;
				}
		}
	for (i=3; i<14; ++i)
		{
			if (tong[i] < 3)
				continue;
			tot=1, j=i+1;
			while (tong[j] >= 3)
				tot++, j++;
			if (tot < 2)
				continue;
			for (j=2; j<=tot; ++j)
				{
					for (k=0; k<j; ++k)
						tong[i+k]-=3;
					dfs(dep+1);
					for (k=0; k<j; ++k)
						tong[i+k]+=3;
				}
		}
	i=j=k=l=0;
	for (tot=2; tot<15; ++tot)
		if (!tong[tot])
			continue;
		else if (tong[tot] == 1)
			l++;
		else if (tong[tot] == 2)
			k++;
		else if (tong[tot] == 3)
			j++;
		else if (tong[tot] == 4)
			i++;
	if (tong[0] == 2)
		ans=min(ans,dep+cal(i,j,k,l)+1);
	l+=tong[0];
	// if (tong[0] == 2)
	// 	k++;
	// else if (tong[0] == 1)
	// 	l++;
	ans=min(ans,dep+cal(i,j,k,l));
}
inline void work()
{
	RG int i,x;
	for (i=1; i<=n; ++i)
		x=gi(), tong[x]++, x=gi();
	tong[14]=tong[1];
	ans=n;
	dfs(0);
	printf("%d\n",ans);
	for (i=0; i<15; ++i)
		tong[i]=0;
}
int main()
{
	RG int t;
	t=gi(), n=gi();
	while (t--)
		work();
	return 0;
}
NOIP 2014【斗地主】的更多相关文章
- NOIP 2014 提高组 题解
		NOIP 2014 提高组 题解 No 1. 生活大爆炸版石头剪刀布 http://www.luogu.org/problem/show?pid=1328 这是道大水题,我都在想怎么会有人错了,没算法 ... 
- Luogu 2668 NOIP 2015 斗地主(搜索,动态规划)
		Luogu 2668 NOIP 2015 斗地主(搜索,动态规划) Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来 ... 
- Luogu 1351 NOIP 2014 联合权值(贪心,计数原理)
		Luogu 1351 NOIP 2014 联合权值(贪心,计数原理) Description 无向连通图 G 有 n 个点,n-1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 Wi, ... 
- noip 2014 提高组初赛
		noip 2014 提高组初赛 一. TCP协议属于哪一层协议( ) A. 应用层 B. 传输层 C. 网络层 D. 数据链路层 B TCP(传输控制协议) 若有变量int a; float: x, ... 
- 洛谷P1328==codevs3716 生活大爆炸版石头剪刀布[NOIP 2014 day1 T1]
		P1328 生活大爆炸版石头剪刀布 1.8K通过 2.6K提交 题目提供者2014白永忻 标签模拟NOIp提高组2014 难度普及- 提交该题 讨论 题解 记录 最新讨论 Who can help m ... 
- noip 2014 总结
		2014 年的noip 已经结束了,成绩从个人而言不是特别的理想,从今年题的逗的程度,本来是个xxx 就被玩脱了= = 当然现在后悔事没有用的了,不过第二天全屏技术的在最后一小时看到了两道题的错误,然 ... 
- NOIP 2014 pj & tg
		由于我太弱,去了pj组= = ============================== T1: 傻逼暴力 T2: 傻逼暴力+判断+更新 T3: 手画一下就知道了.算出这个点在第几圈,再使劲yy下在 ... 
- [NOIP 2014复习]第三章:动态规划——NOIP历届真题回想
		背包型动态规划 1.Wikioi 1047 邮票面值设计 题目描写叙述 Description 给定一个信封,最多仅仅同意粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定全部的邮票数量都 ... 
- 基础算法(搜索):NOIP 2015 斗地主
		Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3& ... 
随机推荐
- 国内最受欢迎的7大API供应平台对比和介绍
			俗话说“巧妇难为无米之炊”,数据源就是数据产生价值中的那些大米.那大数据时代企业需要哪些数据呢?根据我个人理解我觉得可以大致分为以下几类: 1.(内部)企业自身业务生产经营环节产生的内部数据[包括销售 ... 
- struts2获取ServletContext对象
			CreateTime--2017年9月7日09:24:40 Author:Marydon struts2获取ServletContext对象 需要导入: import javax.servlet. ... 
- 【Excle数据透视】如何用含有单元格的数据来创建数据透视
			取消合并单元格,填充相同内容项,然后创建数据透视表. 如下图:需要使用数据创建数据透视表 步骤一 开始→格式刷,然后对单元格区域G2:G15使用格式刷功能,保留合并单元格格式 步骤二 选中A2:A18 ... 
- jquery 创建jquery的dom对象---------------获取自身的html节点及其子节点的html
			1.var domObj = $("<dom>"); 2.var a = $("<a href='www.baidu.com'>"); ... 
- BFC简析
			一.BOX模型 box是CSS中布局的基本单位,而不同类型的box,会参与不同的Formatting Context(一个决定如何渲染文档的容器),box内的元素会以不同的方式渲染. block-le ... 
- mysql 配置 安装和 root password 更改
			第一步: 修改my.ini文件,替换为以下内容 (skip_grant_tables***重点) # For advice on how to change settings please see # ... 
- TRUNCATE 不能引发触发器
			我在使用phpmyadmin清空时发现这个问题 
- JavaScript--基于对象的脚本语言学习笔记(一)
			1.两种嵌入js的方式 使用javascript前缀构建url:<a href="javascript:alert('执行JavaScript. .')">执行j ... 
- IPv4地址(一)概述
			IPv4地址的长度是多少? IPv4地址是如何表示的? IPv4地址的构成以及每一部分所起到的作用和占的位数特点? IPv4地址长度为32位. IPv4地址分为两部分:网络号和主机号 网络号部分惟一地 ... 
- 多媒体开发之---live555的多线程支持,原本只是单线程,单通道
			1)我对Live555进行了一次封装,但是Live555 是单线程的,里面定义的全局变量太多,我封装好dll库后,在客户端调用,因为多个对话框中要使用码流,我就定义了多个对象从设备端接收码流,建立多个 ... 
