Luogu2540 斗地主增强版(搜索+动态规划)
单纯的暴搜似乎还是很好写的,然而过不了。出完顺子之后答案是可以dp出来的,于是大力搜然后大力dp就好了。
dp时强行讨论完了几乎所有拆牌情况,理性愉悦一发。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int T,n,cnt[],f[][][][][],ans;//1:2 2~12:3~K 13:A 14 15:ghost
void dfs(int k,int step);
void threestraight(int k,int step)
{
for (int i=;i<=;i++)
if (cnt[i]>=&&cnt[i+]>=)
{
cnt[i]-=,cnt[i+]-=;dfs(k-,step+);
int t=i+;while (cnt[t+]>=) t++,cnt[t]-=,dfs(k-(t-i+)*,step+);
while (t>=i) cnt[t]+=,t--;
}
}
void twostraight(int k,int step)
{
for (int i=;i<=;i++)
if (cnt[i]>=&&cnt[i+]>=&&cnt[i+]>=)
{
cnt[i]-=,cnt[i+]-=,cnt[i+]-=;dfs(k-,step+);
int t=i+;while (cnt[t+]>=) t++,cnt[t]-=,dfs(k-((t-i+)<<),step+);
while (t>=i) cnt[t]+=,t--;
}
}
void onestraight(int k,int step)
{
for (int i=;i<=;i++)
if (cnt[i]&&cnt[i+]&&cnt[i+]&&cnt[i+]&&cnt[i+])
{
cnt[i]--,cnt[i+]--,cnt[i+]--,cnt[i+]--,cnt[i+]--;dfs(k-,step+);
int t=i+;while (t<&&cnt[t+]) t++,cnt[t]--,dfs(k-(t-i+),step+);
while (t>=i) cnt[t]++,t--;
}
}
void dfs(int k,int step)
{
int t[]={};
for (int i=;i<=;i++) if (cnt[i]) t[cnt[i]]++;
t[]=cnt[]+cnt[];
ans=min(ans,step+f[t[]][t[]][t[]][t[]][t[]]);
if (step+(k>)>=ans) return;
if (k==) return;
threestraight(k,step);
twostraight(k,step);
onestraight(k,step);
}
inline void update(int &x,int y){x=min(x,y);}
void dp()
{
memset(f,,sizeof(f));
f[][][][][]=;
for (int i=;i<=n;i++)
for (int x=;x<=i;x++)
for (int y=;y*<=i-x;y++)
for (int z=;z*<=i-x-y*;z++)
for (int t=;t*<=i-x-y*-z*;t++)
for (int g=;g<=min(,i-x-y*-z*-t*);g++)
{
if (x) update(f[x][y][z][t][g],f[x-][y][z][t][g]+);
if (y) update(f[x][y][z][t][g],f[x][y-][z][t][g]+);
if (y) update(f[x][y][z][t][g],f[x+][y-][z][t][g]+);
if (z) update(f[x][y][z][t][g],f[x][y][z-][t][g]+);
if (z) update(f[x][y][z][t][g],f[x][y+][z-][t][g]+);
if (z) update(f[x][y][z][t][g],f[x+][y][z-][t][g]+);
if (t) update(f[x][y][z][t][g],f[x][y][z][t-][g]+);
if (t) update(f[x][y][z][t][g],f[x][y][z+][t-][g]+);
if (t) update(f[x][y][z][t][g],f[x][y+][z][t-][g]+);
if (t) update(f[x][y][z][t][g],f[x+][y][z][t-][g]+);
if (g) update(f[x][y][z][t][g],f[x][y][z][t][g-]+);
if (g==) update(f[x][y][z][t][g],f[x][y][z][t][g-]+);
//part 1 only one
if (z&&x) update(f[x][y][z][t][g],f[x-][y][z-][t][g]+);
if (z&&y) update(f[x][y][z][t][g],f[x+][y-][z-][t][g]+);
if (z>=) update(f[x][y][z][t][g],f[x][y+][z-][t][g]+);
if (z&&g) update(f[x][y][z][t][g],f[x][y][z-][t][g-]+);
if (t&&y) update(f[x][y][z][t][g],f[x+][y-][z][t-][g]+);
if (t>=) update(f[x][y][z][t][g],f[x+][y][z+][t-][g]+);
if (t&&g) update(f[x][y][z][t][g],f[x][y][z][t-][g-]+);
//part 2 three with one
if (z&&y) update(f[x][y][z][t][g],f[x][y-][z-][t][g]+);
if (z>=) update(f[x][y][z][t][g],f[x+][y][z-][t][g]+);
if (z&&t) update(f[x][y][z][t][g],f[x][y+][z-][t-][g]+);
if (t&&y) update(f[x][y][z][t][g],f[x+][y-][z][t-][g]+);
if (t&&z) update(f[x][y][z][t][g],f[x+][t][z-][t-][g]+);
if (t>=) update(f[x][t][z][t][g],f[x+][y+][z][t-][g]+);
//part 3 three with two
if (t)
{
if (x>=) update(f[x][y][z][t][g],f[x-][y][z][t-][g]+);
if (x&&g) update(f[x][y][z][t][g],f[x-][y][z][t-][g-]+);
if (y) update(f[x][y][z][t][g],f[x][y-][z][t-][g]+);
if (y>=) update(f[x][y][z][t][g],f[x+][y-][z][t-][g]+);
if (y&&g) update(f[x][y][z][t][g],f[x+][y-][z][t-][g-]+);
if (z) update(f[x][y][z][t][g],f[x+][y][z-][t-][g]+);
if (z&&x) update(f[x][y][z][t][g],f[x-][y+][z-][t-][g]+);
if (z&&y) update(f[x][y][z][t][g],f[x+][y][z-][t-][g]+);
if (z>=) update(f[x][y][z][t][g],f[x][y+][z-][t-][g]+);
if (z&&g) update(f[x][y][z][t][g],f[x][y+][z-][t-][g-]+);
if (t>=) update(f[x][y][z][t][g],f[x][y+][z][t-][g]+);
if (t>=) update(f[x][y][z][t][g],f[x][y][z+][t-][g]+);
if (t>=&&x) update(f[x][y][z][t][g],f[x-][y][z+][t-][g]+);
if (t>=&&y) update(f[x][y][z][t][g],f[x+][y-][z+][t-][g]+);
if (t>=&&z) update(f[x][y][z][t][g],f[x][y+][z][t-][g]+);
if (t>=&&g) update(f[x][y][z][t][g],f[x][y][z+][t-][g-]+);
if (g>=) update(f[x][y][z][t][g],f[x][y][z][t-][g-]+);
//part 4 four with one
if (y>=) update(f[x][y][z][t][g],f[x][y-][z][t-][g]+);
if (z>=) update(f[x][y][z][t][g],f[x+][y][z-][t-][g]+);
if (y&&z) update(f[x][y][z][t][g],f[x+][y][z-][t-][g]+);
if (t>=&&z) update(f[x][y][z][t][g],f[x+][y+][z-][t-][g]+);
if (t>=) update(f[x][y][z][t][g],f[x][y][z][t-][g]+);
if (t>=) update(f[x][y][z][t][g],f[x][y+][z][t-][g]+);
//part 5 four with two
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("2540.in","r",stdin);
freopen("2540.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
T=read(),n=read();
dp();
while (T--)
{
ans=n;memset(cnt,,sizeof(cnt));
for (int i=;i<=n;i++)
{
int x=read(),y=read();
if (x==) cnt[y+]++;
else if (x==) cnt[]++;
else if (x==) cnt[]++;
else cnt[x-]++;
}
dfs(n,);
cout<<ans<<endl;
}
return ;
}
Luogu2540 斗地主增强版(搜索+动态规划)的更多相关文章
- [Luogu2540][NOIP2016]斗地主增强版(搜索+DP)
增强版就是原版中两鬼不算对子的版本. 先爆搜出完所有对子,剩下的牌DP处理. 考虑每个数码的拆牌情况,最多可能被拆成5种情况:1+1+1+1,1+1+2,1+3,2+2,4.故DP状态数最多为5^13 ...
- luogu2540 斗地主增强版
题目大意 给你一副手牌,没有飞机带翅膀,按斗地主的规则,求将所有牌打出的最少次数. 题解 先不考虑顺子 我们已经知道花色对牌没有影响,那么如果不考虑顺子,每个牌具体是什么数字我们也用不着知道,我们关心 ...
- Luogu 2540 斗地主增强版(搜索,动态规划)
Luogu 2540 斗地主增强版(搜索,动态规划) Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游 ...
- P2540 斗地主增强版
P2540斗地主增强版 参考大佬题解 思路:顺子暴力搜,剩下的牌我不会贪心所以用记忆化搜索(或者dp): 注意:双王不能当对,二不算顺子 代码 #include <cstdio> #inc ...
- 洛谷 题解 P2540 【斗地主增强版】
[分析] 暴力搜顺子,贪心出散牌 为什么顺子要暴力? 玩过斗地主的都知道,并不是出越长的顺子越好,如果你有一组手牌,3,4,5,6,7,6,7,8,9,10,你一下把最长的出了去,你会单两张牌,不如出 ...
- 【NOIP2015】斗地主 D1 T3 及 增强版 (送命题)
恶心送命模拟题 暴搜顺子,DP预处理剩下的. 由于官方数据太水,很多情况没有讨论的都能过普通版本,想要测试自己代码正确性的同学们可以交交这道题,有很多dalao给出了hack数据 : Luogu P2 ...
- 《zw版·delphi与halcon系列原创教程》zw版_THOperatorSetX控件函数列表 v11中文增强版
<zw版·delphi与halcon系列原创教程>zw版_THOperatorSetX控件函数列表v11中文增强版 Halcon虽然庞大,光HALCONXLib_TLB.pas文件,源码就 ...
- 微慕WordPress小程序增强版
2017年1月9日,张小龙在2017微信公开课Pro上发布的微信小程序正式上线.在过去的2年多的时间里,微信小程序领头,各大互联网平台也不甘落后,陆续推出自己的小程序.2018年7月4日,百度智能小程 ...
- 将表里的数据批量生成INSERT语句的存储过程 增强版
将表里的数据批量生成INSERT语句的存储过程 增强版 有时候,我们需要将某个表里的数据全部或者根据查询条件导出来,迁移到另一个相同结构的库中 目前SQL Server里面是没有相关的工具根据查询条件 ...
随机推荐
- 成都Uber优步司机奖励政策(1月21日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 1 多任务fork Unix/Linux/Mac
# 注意,fork函数,只在Unix/Linux/Mac上运行,windows不可以 1.如下程序,来模拟“唱歌跳舞”这件事情 #-*- coding:utf-8 -*- import time de ...
- P1294 高手去散步
P1294 高手去散步 题目背景 高手最近谈恋爱了.不过是单相思.“即使是单相思,也是完整的爱情”,高手从未放弃对它的追求.今天,这个阳光明媚的早晨,太阳从西边缓缓升起.于是它找到高手,希望在晨读开始 ...
- 角色 RESOURCE、CONNECT、DBA具有的权限
角色 RESOURCE.CONNECT.DBA具有的权限 select grantee,privilege from dba_sys_privs where grantee='RESOURCE' or ...
- Siki_Unity_1-4_C#编程(零基础)
1-4 C#编程(零基础) 任务1:第一章课程资料 任务2:简介 任务3:安装设置IDE工具 Unity内置IDE:MonoDevelop 推荐Visual Studio 下载/安装 VS Commu ...
- [JSON].getObj( keyPath )
语法:[JSON].getObj( keyPath ) 返回:[JSON] 说明:返回指定键名路径的JSON对象,指定键名路径不存在时返回空的toJson对象(强烈建议使用 [JSON].exists ...
- [Clr via C#读书笔记]Cp17委托
Cp17委托 简单介绍 delegate回调函数机制,可以理解存储函数地址的变量类型: 类型安全: 引用类型支持逆变和协变: 回调 静态方法,实例方法 委托的本质 所有的委托都派生自System.Mu ...
- 用 splice 函数分别实现 push、pop、shift、unshift 的方法
主要需要注意的是不同方法他们本身返回的值应该是什么,是数组当前的长度,还是取出的元素的值,再在splice函数里面进行相应的return就可以了.具体如下: 用 splice函数实现 push方法 f ...
- Matlab带比较方法的快排
首先是主方法QUCIKSORT:(从小到大排列) function [A]=QUICKSORT(A,Low,high,mdat) set(,) if Low<high [A,w]=SPLITIO ...
- parity注记词和地址
remix skilled curled cobweb tactics koala bartender precinct energize exes ridden cohesive 0x00EeC52 ...