LUOGU 2593 : [Zjoi2006] 超级麻将
解题思路
直接爆搜全T。。状态数太多了,所以我们考虑贪心+剪枝。贪心:先拿三个连着的,再拿四个一样的,再拿三个一样的,最后拿两个一样的这样的搜索顺序最优,两个的放最后是因为只要这样的一个,三个连着的放开头是因为这样可以照顾到后面很少的情况。这样肯定还是T,我们考虑剪枝,用hash减。考虑如果数据为
12 0 1 0 0 0…. 这样的 ,我们第一种搜的方案是 a[1]里拿三个4,后面发现不行,返回。第二种方案是a[1]拿四个3,发现这两种方案拿完a[1]后 剩下的序列都是0 1 0 0…,所以将剩下的序列hash一下存到set里,如果再次遇到就直接返回false,注意这里直接去模会T的很惨,所以要用到unsigned long long 里的自然溢出。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#define ULL unsigned long long
using namespace std;
const int MAXN = 105;
const ULL base = 131ll;
int n,a[MAXN];
ULL hash[MAXN],sum;
set<ULL> s;
bool dfs(int x,bool two,ULL S){
if(s.find(S)!=s.end()) return 0;
s.insert(S);
while(a[x]==0 && x<=100) x++;
if(x==101) return two;
if(a[x]>0 && a[x+1]>0 && a[x+2]>0) {
a[x]--;a[x+1]--;a[x+2]--;
if(dfs(x,two,S-hash[x]-hash[x+1]-hash[x+2])) return 1;
a[x]++;a[x+1]++;a[x+2]++;
}
if(a[x]>=4) {
a[x]-=4;
if(dfs(x,two,S-hash[x]*4)) return 1;
a[x]+=4;
}
if(a[x]>=3){
a[x]-=3;
if(dfs(x,two,S-hash[x]*3)) return 1;
a[x]+=3;
}
if(a[x]>=2 && !two){
a[x]-=2;
if(dfs(x,1,S-hash[x]*2-hash[100])) return 1;
a[x]+=2;
}return 0;
}
int main(){
// freopen("rand.txt","r",stdin);
// freopen("B.txt","w",stdout);
scanf("%d",&n);
hash[1]=1ll;
for(register int i=2;i<=100;i++) {
hash[i]=hash[i-1]*base;
}
for(register int i=1;i<=n;i++){
sum=0;
for(register int j=1;j<=100;j++){
scanf("%d",&a[j]);sum+=hash[j]*a[j];
}
s.clear();
puts(dfs(1,0,sum)==true?"Yes":"No");
}
return 0;
}
LUOGU 2593 : [Zjoi2006] 超级麻将的更多相关文章
- 洛谷2593 [ZJOI2006]超级麻将——可行性dp
题目:https://www.luogu.org/problemnew/show/P2593 发现三个连续牌的影响范围只有3.相同牌的影响范围只有1之后就可以dp了. O(100^7)T飞. #inc ...
- [LUOGU] P2593 [ZJOI2006]超级麻将
f[a][b][c][i]表示考虑到第i个,第i位用了b个,第i-1位用了a个,此时有将/无将(c=1/0)的情况是否可达. 转移分以下几类: 1.调一个将 f[a][b][1][i]|=f[a][b ...
- [ZJOI2006]超级麻将
题目描述 很多人都知道玩麻将,当然也有人不知道,呵呵,不要紧,我在这里简要地介绍一下麻将规则: 普通麻将有砣.索.万三种类型的牌,每种牌有1~9个数字,其中相同的牌每个有四张,例如1砣~9砣,1索~9 ...
- [ZJOI2006]超级麻将(可行性dp)
题目描述 要判断某人是否胡牌,显然一个弱智的算法就行了,某中学信息学小组超级麻将迷想了想,决定将普通麻将改造成超级麻将. 所谓超级麻将没有了砣.索.万的区分,每种牌上的数字可以是1~100,而每种数字 ...
- [ZJOI2006]超级麻将(动规)
题目描述 很多人都知道玩麻将,当然也有人不知道,呵呵,不要紧,我在这里简要地介绍一下麻将规则: 普通麻将有砣.索.万三种类型的牌,每种牌有1~9个数字,其中相同的牌每个有四张,例如1砣~9砣,1索~9 ...
- [bzoj1860 ZJOI2006] 超级麻将 (线性dp)
传送门 Description Input 第一行一个整数N(N<=100),表示玩了N次超级麻将. 接下来N行,每行100个数a1..a100,描述每次玩牌手中各种牌的数量.ai表示数字为i的 ...
- [Luogu2593] [ZJOI2006]超级麻将
题目地址 :https://www.luogu.org/problemnew/show/P2593. 无脑DP(虽说是抄的额) #include <iostream> #include & ...
- 洛谷 P2593 [ZJOI2006]超级麻将【dp】
设f[i][j][k][0/1]表示选到i时,i-1选j张,i选k张,之前选的所有牌是否选择了对子 然后分情况讨论转移即可 #include<iostream> #include<c ...
- bzoj 1860: [Zjoi2006]Mahjong麻将 题解
[原题] 1860: [Zjoi2006]Mahjong麻将 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 211 Solved: 122 [Subm ...
随机推荐
- Nodejs之路(一)—— Nodejs入门
不知不觉,现在已经习惯学一点东西,就写博客记录一下.这次学习Nodejs主要是在B站上看的视频教程,感觉讲的很是不错,所以我想把在看视频学习过程中的一些重要知识点记录下来方便以后自己快速查阅. --- ...
- vue 实现单选框
参考:https://blog.csdn.net/qq_42221334/article/details/81630634 效果: vue: <template> <div> ...
- 初识splay
这东西都没什么板子着实让我很难受啊,只能到网上抄抄补补, 记下两个用到的博客 https://blog.csdn.net/clove_unique/article/details/50630280 h ...
- goland破解
PyCharm是由著名的JetBrains公司所打造的一款功能强大的Python IDE,它具有一般IDE都具备的功能,并且使用起来非常方便好用.最近需求PyCharm激活码的网友非常多,小编就在这里 ...
- Java校验时间段重叠
1.需求 要求保存每一条数据的startTime.endTime的中间时间段是唯一的,跟其他数据时间段不能存在冲突 比如: (2019-03-01 -> 2019-03-03 ) (2019- ...
- new运算符与malloc函数(还需要修改)
细说new与malloc的10点区别 C++ 自由存储区是否等价于堆? 浅谈new/delete和malloc/free的用法与区别 new和malloc都是在对上开辟内存,但尽量使用new. 使用m ...
- ionic Hide tabs 实现
1.指令代码 directiveMod.directive('hideTabs',function($rootScope){ return { restrict:'AE', link:function ...
- Django项目:CRM(客户关系管理系统)--69--59PerfectCRM实现king_admin行内编辑
#base_admin.py # ————————24PerfectCRM实现King_admin自定义操作数据———————— from django.shortcuts import render ...
- webpack 处理图片文件
1. 安装 file-loader html-loader npm install file-loader html-loader --save-dev 其中html-loader生效需配合 html ...
- 【DM8168学习笔记1】帮您快速入门 TI 的 Codec Engine
http://www.ti.com.cn/general/cn/docs/gencontent.tsp?contentId=61575 德州仪器半导体技术(上海)有限公司 通用DSP 技术应用工程师 ...