洛谷 2668&2540 斗地主——搜索+贪心+dp
题目: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的更多相关文章
- 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)
洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...
- 洛谷 2921 记忆化搜索 tarjan 基环外向树
洛谷 2921 记忆化搜索 tarjan 传送门 (https://www.luogu.org/problem/show?pid=2921) 做这题的经历有点玄学,,起因是某个random题的同学突然 ...
- 洛谷 P3177 [HAOI2015]树上染色 树形DP
洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...
- 洛谷 P4072 [SDOI2016]征途 斜率优化DP
洛谷 P4072 [SDOI2016]征途 斜率优化DP 题目描述 \(Pine\) 开始了从 \(S\) 地到 \(T\) 地的征途. 从\(S\)地到\(T\)地的路可以划分成 \(n\) 段,相 ...
- 洛谷P1282 多米诺骨牌 (DP)
洛谷P1282 多米诺骨牌 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中 ...
- 洛谷P1880 石子合并(区间DP)(环形DP)
To 洛谷.1880 石子合并 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1 ...
- 洛谷P1063 能量项链(区间DP)(环形DP)
To 洛谷.1063 能量项链 题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的 ...
- 洛谷P1074 靶形数独 [搜索]
题目传送门 题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z 博士拿出了 ...
- 【洛谷 P1667】 数列 (贪心)
题目链接 对于一个区间\([x,y]\),设这个区间的总和为\(S\) 那么我们在前缀和(设为\(sum[i]\))的意义上考虑到原操作其实就是\(sum[x−1]+=S\) , \(sum[x]+S ...
随机推荐
- C#使用CurrentUICulture切换语言
1. 创建2个窗口 2. 窗口1属性Localizable设置为True,Language选择英语(美国) 然后把窗口1中控件的Text由中文编辑成英文,Form2一样设置. 此时,Form1 ...
- 使用Cout输出String和CString对象
CString和string都是一个类,不同的是CString主要用于MFC或者是ATL编程中,而string则多用于Windows控制台编程中 在实际编程过程中,我们经常用到string或者是CSt ...
- [ssh新闻公布系统三]存储新闻
一.存储新闻dao方法 在NewsDao.java中新增存储新闻的saveOrupdate方法 public void saveOrupdate(News news){ getSession().sa ...
- Jememeter和Loadrunner测试MySQL性能
From:http://blog.csdn.net/testingstar/article/details/60579454 MySQL数据库性能测试的方法 前置条件: 安装系统:windows 7 ...
- Python遍历列表
#循环遍历列表 nums = [ss,gg,e,fff,bb] #while循环遍历,但是不推荐使用,因为还要把列表的元素数出来 i = 0 while i<5: print(nums[i]) ...
- Apache Server与多个独立Tomcat集成
取经自http://www.ramkitech.com/2012/03/virtual-host-apache-httpd-server-tomcat.html 继续干Tomcat和Apache Se ...
- 多媒体开发之编码gop---什么是GOP
所谓GOP,意思是画面组,MPEG格中的帧序列,分为I.P.B三种,如排成IBBPBBPBBPBBPBBP...样式,这种连续的帧图片组合即为GOP(画面群,GROUP OF PICTURE),是MP ...
- 怎么样获得泛型T的Class对象?
public class GenClass<T> { private Class<T> entityClass; } public class Test { public st ...
- oracle 控制文件多路复用
网上有很多关于控制文件的操作,我大概看了下.有很多都是炒来炒去转来转去.下面以自己理解和操作为例来对oracle的控制文件进行下介绍. 首先介绍下控制文件 在oralce数据库中,控制文件是一个很小的 ...
- 功能强大的Xcode辅助工具Faux Pas:帮你找到各种隐形的bug
本文转载至 http://www.cocoachina.com/industry/20140804/9307.html Faux Pas(Beta版下载地址)是一个Xcode辅助工具,用以检查Xcod ...