Luogu P2540 NOIP2015提高组 斗地主 加强版 题解 [ 紫 ] [ 深搜 ] [ 剪枝 ]

news/2025/1/21 18:49:29/文章来源:https://www.cnblogs.com/zhr0102/p/18684229

斗地主:一步一步推性质就能做出来的剪枝题。

这题思路和小木棒的剪枝思路极其相似,剪枝的角度都差不多。

其实大部分搜索剪枝题都是先观察性质,列出性质后选择几个比较关键且代码好写的性质进行剪枝,特别要注意避免重复搜索相同状态的剪枝。同时注意想好了之后再写代码。

并且大部分搜索题会把正向的搜索树 hack 得很大,当被卡的时候不妨试试倒着搜索,可能有奇效。

思路

观察题目,我们可以发现如下几点性质:

  • 出牌的顺序不影响最终的结果,先出某一组牌和后出某一组牌本质是一样的。
  • 最后只剩下单牌、对子、三张牌、炸弹和王炸的时候,我们可以贪心地扫一遍统计至少存在一张牌的码数的个数,特判掉大小王得出答案。
  • 在顺子和带牌中,顺子打出的方案数一般比带牌的方案数更少。

因此,我们可以设计出如下剪枝方案:

  • 将搜索阶段拆解为 \(6\) 步,依次完成。分别是三顺子、双顺子、单顺子、四带二、三带一和二、最后剩下的统一出掉,大王小王绑一起出。
  • 记录下当前的搜索阶段 \(p\),以及上一次在同阶段最后搜索到的牌 \(lst\)。每次接着 \(lst\) 后面来搜索,避免搜到重复状态。
  • 把三顺子、双顺子、单顺子、四带二、三带一和二全部出完之后,我们可以线性扫一遍算出最终的答案,避免了搜索多余状态。

实现的时候对每个搜索阶段分步实现,代码在写顺子和带牌内部时可以稍作修改之后重复利用。

时间复杂度玄学,但是能过大部分数据。

代码

#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
using pi=pair<int,int>;
/*
三顺子 1
双顺子 2
单顺子 3
四带二 4
三带一、二 5
最后剩下的统一出掉,大王小王绑一起出。 
1~11 3~K
12 A
13 2
14 little
15 big
*/
int tot[20],ans=0x3f3f3f3f,now=0,n;
void dfs(int p,int lst)
{if(p>=6){int cur=0;for(int i=1;i<=15;i++)if(tot[i])cur++;if(tot[14]&&tot[15])cur--;ans=min(ans,now+cur);return;}if(p==1){int pre=0;for(int i=1;i<=12;i++){if(tot[i]>=3)pre++;else pre=0;if(pre>=2&&i>=lst){int tmp[20];memcpy(tmp,tot,sizeof(tmp));tot[i]-=3;for(int j=2;j<=pre;j++){tot[i-j+1]-=3;now++;dfs(p,i);now--;}memcpy(tot,tmp,sizeof(tmp));}}dfs(p+1,1);return;}if(p==2){int pre=0;for(int i=1;i<=12;i++){if(tot[i]>=2)pre++;else pre=0;if(pre>=3&&i>=lst){int tmp[20];memcpy(tmp,tot,sizeof(tmp));tot[i]-=2;tot[i-1]-=2;for(int j=3;j<=pre;j++){tot[i-j+1]-=2;now++;dfs(p,i);now--;}memcpy(tot,tmp,sizeof(tmp));}}dfs(p+1,1);return;		}if(p==3){int pre=0;for(int i=1;i<=12;i++){if(tot[i]>=1)pre++;else pre=0;if(pre>=5&&i>=lst){int tmp[20];memcpy(tmp,tot,sizeof(tmp));tot[i]-=1;tot[i-1]-=1;tot[i-2]-=1;tot[i-3]-=1;for(int j=5;j<=pre&&i-j+1>=1;j++){tot[i-j+1]-=1;now++;dfs(p,i);now--;}memcpy(tot,tmp,sizeof(tmp));}}dfs(p+1,1);return;		}if(p==4){for(int i=1;i<=13;i++){if(tot[i]>=4){tot[i]-=4;for(int j=1;j<=15;j++){if(tot[j]<=0)continue;for(int k=1;k<=15;k++){if(tot[k]<=0)continue;if(tot[j]&&tot[k]&&(j!=k||tot[j]>=2)){tot[j]--;tot[k]--;now++;dfs(p,i);tot[j]++;tot[k]++;now--;}if(tot[j]>=2&&tot[k]>=2&&(j!=k||tot[j]>=4)){tot[j]-=2;tot[k]-=2;now++;dfs(p,i);tot[j]+=2;tot[k]+=2;now--;}			}}tot[i]+=4;}}dfs(p+1,1);return;}if(p==5){for(int i=1;i<=13;i++){if(tot[i]>=3){tot[i]-=3;for(int j=1;j<=15;j++){if(tot[j]>=1){tot[j]--;now++;dfs(p,i);tot[j]++;now--;}if(tot[j]>=2){tot[j]-=2;now++;dfs(p,i);tot[j]+=2;now--;}}tot[i]+=3;}}dfs(p+1,1);return;}
}
void solve()
{memset(tot,0,sizeof(tot));ans=0x3f3f3f3f;now=0;for(int i=1;i<=n;i++){int a,b;cin>>a>>b;if(3<=a&&a<=13)tot[a-2]++;else if(a<3&&a>0)tot[a+11]++;else tot[b+13]++;}dfs(1,1);cout<<ans<<'\n';
}
int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t;cin>>t>>n;while(t--)solve();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/872928.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《操作系统真象还原》第九章 线程(一) 在内核中实现线程

本文是对《操作系统真象还原》第九章(一)学习的笔记,欢迎大家一起交流。第九章 线程(一) 在内核中实现线程 本文是对《操作系统真象还原》第九章(一)学习的笔记,欢迎大家一起交流。 我们在本节的任务:创建并初始化PCB 模拟pthread_create函数创建线程并执行线程函数首…

1.21 javaweb学习

今天学习了html中onsubmit的使用 onsubmit事件处理器是专门用于表单(form)的提交事件,所以要注意div标签是不能直接使用onsubmit的 今天在作业项目中出现了这样的问题,将onsubmit放在了div标签中,导致数据无法被正常处理,上传数据有误,修改至form后问题解决 修改前数据提…

思通数科舆情系统的分析报告主要内容及其市场价值探析

思通数科舆情系统的分析报告广泛应用于以下几个领域: (1) 企业品牌管理与危机预警:系统能够自动发出警报,为企业的公关部门提供应对策略和决策依据,帮助企业迅速做出反应,避免危机的进一步扩展。 (2) 政府舆情监管与社会治理:政府部门能够利用该系统的热点事件排名、舆情…

北汇信息致客户的一封感谢信

北汇信息致客户的一封感谢信尊敬的客户:感谢您选择北汇信息!2024年是不平凡的一年,中国汽车产量再创新高,出海与内卷挑战不断。北汇信息作为汽车电子测试领域的服务商,秉承“价值创造、共享成功”的理念,一直致力于为国内外汽车客户提供优质的产品和服务,共同面对这些挑…

001 修改博客园侧边栏的顺序

打开配置页:https://i.cnblogs.com/settings在“博客侧边栏公告”添加代码<script> $(document).ready(function(){//returnvar list=[sidebar_recentcomments,//最新评论sidebar_categories,//随笔分类、随笔档案sidebar_toptags,//我的标签sidebar_shortcut,//常用链接…

销售进阶:三步提问法,掌握客户心理

在销售行业,时间就是金钱,我们必须争分夺秒地搞定客户。但也不能盲目行动,而要稳扎稳打。关键在于快速抓住客户需求,而客户往往不会主动透露他们的需求,甚至自己都不清楚自己想要什么。这就需要我们通过巧妙的提问来破局,否则忙活半天也只是白费力气。 最让人头疼的是,跟…

寒假集训笔记 | | 第一课

C++STL --第一课 C标准库常用函数<cstring>memset() 暴力清空 char str[10]; memset(str,0,sizeof(str));<cmath>三角函数、指数函数、浮点取整函数<cstdlib>qsort() C语言快排 rand() 随机数 malloc() free() C语言动态内存分配<cctype>isdigit()…

Svelte 最新中文文档翻译(1)—— 概述与入门指南

前言 Svelte,一个非常“有趣”、用起来“很爽”的前端框架。从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1:Svelte 以其独特的编译时优化机制著称,具有轻量级、高性能、易上手等特性,非常适合构…

平面二连杆机构的动力学方程

动力学研究物体的运动和作用力之间的关系。机器人动力学问题有两类:一是已知机器人各关节的驱动力或力矩,求解机器人各关节的位置、速度和加速度,这是动力学正问题;二是已知各关节的位置、速度和加速度,求各关节所需的驱动力或力矩,这是动力学逆问题。机器人的动力学正问…

【红队】C2框架:Covenant

一、项目介绍 Covenant是一个.NET开发的C2(command and control)框架,旨在突出.NET的攻击面,并充当红队成员的协作命令和控制平台,该工具不仅支持Linux,MacOS和Windows,还支持docker容器,最特别的地方是支持动态编译,能够将输入的C#代码上传至C2 Server,获得编译后的文…

3. 使用sql查询csv/json文件内容,还能关联查询?

1. 简介 我们在前面的文章提到了calcite可以支持文件系统的数据源适配, 其实官方已经提供了相应的能力, 其支持csv和json的查询适配, 废话不多说, 直接展示. 2. Maven <!-- calcite文件系统支持 --> <dependency><groupId>org.apache.calcite</groupId>…

一文搞懂 APP 算法备案

今天来给大家好好科普一下超重要的 APP 算法备案,这可是和我们日常使用 APP 以及 APP 运营都息息相关的知识点哦! 什么是算法备案 简单来讲,算法备案就相当于 APP 运营者要把自家 APP 里使用的算法详情,向有关部门进行申报登记。这就如同给算法这个 “幕后大脑” 办一张正式…