题目:https://www.luogu.org/problemnew/show/P2540

发现如果没有顺子,剩下的可以贪心。所以搜索顺子怎么出,然后贪心。

这样只能过不加强版。原因是贪心的时候难以弄3=1+2。3应该是 3带* 还是拆开让4带上?

如这个数据(×后面是个数):3×3,4×1,6×4,7×3,9×1,10×2,11×1,12×4,13×3

  正解应该是把一个3拆成1+2,然后两次4带2,两次3带2。但贪心似乎做不了。

所以应该dp!记录1,2,3,4,王各有几个,就能把“拆”体现在状态转移里了。

自己以“还剩几张牌”为阶段,“拆”就是同层转移了;所以需要注意枚举的顺序,保证先同层转移到自己,再从自己转移。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,M=;
int T,n,a[N][M],nm[],dp[N][N>>][N/][N>>][],fg,ans;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='') ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return fx?ret:-ret;
}
void Mn(int &x,int y){x=min(x,y);}
void calc(int cr)
{
memset(dp,0x3f,sizeof dp); memset(nm,,sizeof nm);
for(int i=;i<=;i++)nm[a[cr][i]]++;
dp[nm[]][nm[]][nm[]][nm[]][fg]=;
int lm1=n,lm2=n>>,lm3=n/,lm4=(n>>);
for(int sm=nm[]+(nm[]<<)+nm[]*+(nm[]<<)+fg;sm>=;sm--)
for(int l=lm4;l>=;l--)
for(int k=lm3;k>=;k--)
for(int j=lm2;j>=;j--)
for(int t=;t<=;t++)
{
int i=sm-(j<<)-k*-(l<<)-t; if(i<)continue;
int d=dp[i][j][k][l][t]; if(d>n-cr)continue;
if(l)Mn(dp[i+][j][k+][l-][t],d);//4=1+3
if(l)Mn(dp[i][j+][k][l-][t],d);//4=2+2
if(k)Mn(dp[i+][j+][k-][l][t],d);//3=1+2
if(j)Mn(dp[i+][j-][k][l][t],d);//2=1+1 d++;
if(l&&i>=)Mn(dp[i-][j][k][l-][t],d);
if(l&&i&&t)Mn(dp[i-][j][k][l-][t-],d);
if(l&&t>=)Mn(dp[i][j][k][l-][],d);
if(l&&j>=)Mn(dp[i][j-][k][l-][t],d); if(k&&j)Mn(dp[i][j-][k-][l][t],d);
if(k&&i)Mn(dp[i-][j][k-][l][t],d);
if(k&&t)Mn(dp[i][j][k-][l][t-],d); if(i)Mn(dp[i-][j][k][l][t],d);
if(j)Mn(dp[i][j-][k][l][t],d);
if(k)Mn(dp[i][j][k-][l][t],d);
if(l)Mn(dp[i][j][k][l-][t],d);
if(t==)Mn(dp[i][j][k][l][t-],d);
if(t==)Mn(dp[i][j][k][l][],d);
}
ans=min(ans,cr+dp[][][][][]);
}
void solve(int cr)
{
if(cr>ans)return;
memcpy(a[cr],a[cr-],sizeof a[cr-]);
for(int i=,j;i<=;i++)
if(a[cr][i]>=&&a[cr][i+]>=)
{
a[cr][i]-=;
for(j=i+;j<=&&a[cr][j]>=;j++)
a[cr][j]-=;
for(j--;j>=i+;j--) solve(cr+),a[cr][j]+=;
a[cr][i]+=;
}
for(int i=,j;i<=;i++)
if(a[cr][i]>=&&a[cr][i+]>=&&a[cr][i+]>=)
{
a[cr][i]-=;a[cr][i+]-=;
for(j=i+;j<=&&a[cr][j]>=;j++)
a[cr][j]-=;
for(j--;j>=i+;j--) solve(cr+),a[cr][j]+=;
a[cr][i+]+=;a[cr][i]+=;
}
for(int i=,j;i<=;i++)
if(a[cr][i]&&a[cr][i+]&&a[cr][i+]&&a[cr][i+]&&a[cr][i+])
{
a[cr][i]--;a[cr][i+]--;a[cr][i+]--;a[cr][i+]--;
for(j=i+;j<=&&a[cr][j];j++)
a[cr][j]--;
for(j--;j>=i+;j--) solve(cr+),a[cr][j]++;
a[cr][i+]++;a[cr][i+]++;a[cr][i+]++;a[cr][i]++;
}
calc(cr-);
}
int main()
{
T=rdn(); n=rdn();
while(T--)
{
ans=N;
memset(a[],,sizeof a[]); fg=;//!
for(int i=,u,v;i<=n;i++)
{
u=rdn(); v=rdn();
if(u)a[][u<=?u+:u-]++;
else fg++;
}
solve();
printf("%d\n",ans);
}
return ;
}

洛谷 2668&2540 斗地主——搜索+贪心+dp的更多相关文章

  1. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

  2. 洛谷 2921 记忆化搜索 tarjan 基环外向树

    洛谷 2921 记忆化搜索 tarjan 传送门 (https://www.luogu.org/problem/show?pid=2921) 做这题的经历有点玄学,,起因是某个random题的同学突然 ...

  3. 洛谷 P3177 [HAOI2015]树上染色 树形DP

    洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...

  4. 洛谷 P4072 [SDOI2016]征途 斜率优化DP

    洛谷 P4072 [SDOI2016]征途 斜率优化DP 题目描述 \(Pine\) 开始了从 \(S\) 地到 \(T\) 地的征途. 从\(S\)地到\(T\)地的路可以划分成 \(n\) 段,相 ...

  5. 洛谷P1282 多米诺骨牌 (DP)

    洛谷P1282 多米诺骨牌 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中 ...

  6. 洛谷P1880 石子合并(区间DP)(环形DP)

    To 洛谷.1880 石子合并 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1 ...

  7. 洛谷P1063 能量项链(区间DP)(环形DP)

    To 洛谷.1063 能量项链 题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的 ...

  8. 洛谷P1074 靶形数独 [搜索]

    题目传送门 题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z 博士拿出了 ...

  9. 【洛谷 P1667】 数列 (贪心)

    题目链接 对于一个区间\([x,y]\),设这个区间的总和为\(S\) 那么我们在前缀和(设为\(sum[i]\))的意义上考虑到原操作其实就是\(sum[x−1]+=S\) , \(sum[x]+S ...

随机推荐

  1. 浅析 rand7生成rand10 方法 之 思想篇(一)

    [问题描写叙述] rand7是一个能生成1-7的随机数.要求利用rand7生成1-10的随机数. [算法思想] 1.组合数学方法 第1次 1 2 3 4 5 6 7 之中用rand7取一个数 第2次从 ...

  2. 关于C语言中二维数组传參————————【Badboy】

    直接上代码: #include void Fun(int *a[],int m,int n)// { printf("%d\t",*a);//[0][0] /* int e[2][ ...

  3. C#中二进制,八进制,十六进制到十进制的相互转换

    1.十进制数字向二进制,八进制,十六进制字符串的转换,使用函数 Convert.ToString(int value, int toBase): 它可以把一个数字转换为不同进制数值的字符串格式,其中t ...

  4. https双向认证訪问管理后台,採用USBKEY进行系统訪问的身份鉴别,KEY的证书长度大于128位,使用USBKEY登录

    近期项目需求,须要实现用USBKEY识别用户登录,採用https双向认证訪问管理后台管理界面,期间碰到过一些小问题,写出来给大家參考下. 1:前期准备工作 USBKEY 硬件:我买的是飞天诚信 epa ...

  5. 深度解析开发项目之 02 - 使用VTMagic实现左右滑动的列表页

    深度解析开发项目之 02 - 使用VTMagic实现左右滑动的列表页 实现效果: 01 - 导入头文件 02 - 遵守代理协议 03 - 声明控制器的属性 04 - 设置声明属性的frame 05 - ...

  6. Effective Java - [2. 创建与销毁对象]

    让对象的创建与销毁在掌控中. Item 1: 使用静态工厂方法而非使用构造函数 public static Boolean valueOf(boolean b) { return b ? Boolea ...

  7. C#注冊表操作汇总

    一.注冊表基本知识 1)       结构 键->项->子项->值项(名称.类型.数据) REG_SZ         字符串 REG_BINARY    二进制 REG_DWORD ...

  8. iOS 浅赋值、深复制、全然复制的知识点梳理验证(附加归档解档)

    写于前: 在之前转载的一片文章中.文中对浅复制和深复制进行了具体的解读,同一时候还提到了深复制(one-level-deep copy).全然复制(true copy)的概念,并指出iOS开发中的深复 ...

  9. STL_算法_查找算法(find、find_if)

    C++ Primer 学习中. .. 简单记录下我的学习过程 (代码为主) find . find_if /**********************线性查找O(n) find(); find_if ...

  10. 【C语言天天练(十九)】restrict关键词

    引言:在内核的系统调用函数里,常常遇到函数的參数使用restrict限定词限定的情况,以下就对该关键词做个总结. 1.restrict关键词是C99特性才加入的,因此在编译使用含有该限定词的程序时,一 ...