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 ...
随机推荐
- 基于vue-cli的vs code设置
vue-cli自带eslin校验,vs code采用下可以设置在保存文件时会自动纠正格式 { // vscode默认启用了根据文件类型自动设置tabsize的选项 "editor.detec ...
- 力扣算法题—460LFU缓存
[题目描述] 设计并实现最不经常使用(LFU)缓存的数据结构.它应该支持以下操作:get 和 put. get(key) - 如果键存在于缓存中,则获取键的值(总是正数),否则返回 -1. put(k ...
- 新启vue_cli项目+引入Element
[1]安装vue_cli vue init webpack 项目名字 [2]安装Element-UI cnpm install element-ui -S //写入dependencies cnpm ...
- css 实现头像周围光圈动态效果
效果: html文件: <img class="userHead" src="xx/user.jpg"> css文件: .userHead{ wid ...
- 网络爬虫技术Jsoup
Jsoup介绍:Jsoup 是一个 Java 的开源HTML解析器,可直接解析某个URL地址.HTML文本内容 Jsoup主要有以下功能: 1. 从一个URL,文件或字符串中解析HTML 2. 使用D ...
- Python-异常处理 使用selenium库自动爬取数据
异常处理 处理程序的报错 语法 捕捉万能异常: try: print(a) except Exception as e: print("你的代码有问题") print(" ...
- ROS urdf和xacro文件详解
视觉标签:visual <visual> <origin xyz="0.0 0.0 0.0" /> <geometry> <box siz ...
- const 有什么用途
可以定义const 常量:const可以修饰函数的参数.返回值,甚至函数的定义体.被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性
- LL(1),LR(0),SLR(1),LALR(1),LR(1)对比与分析
前言:考虑到这几种文法如果把具体内容讲下来肯定篇幅太长,而且繁多的符号对初学者肯定是极不友好的,而且我相信看这篇博客的人已经对这几个文法已经有所了解了,本篇博客的内容只是对 这几个文法做一下对比,加深 ...
- Scrapy下载图片及自定义分类下载路径
配置下载图片的流程如下 在items中定义两个属性,image_urls 和images .image_urls是用来存储需要下载的图片url链接,列表类型: 当文件下载完成后会把相关下载信息存入im ...