【CERC 2014 E】2048
题意
2048曾经是一款风靡全球的小游戏。
今天,我们换一种方式来玩这个小游戏。
你有一个双端队列,你只能把元素从左端或从右端放入双端队列中。一旦放入就不得取出。放入后,若队列中有连续两个相同的元素,它们将自动合并变成一个新的元素——原来那两个元素的和。若新的元素与它相邻的元素相同,则继续合并……
如:双端队列中有2, 4, 16三个元素。若将2从左端插入双端队列中,该队列将变成8, 16。若将2从右端插入双端队列中,该队列将变成2, 4, 16, 2。
一开始,双端队列为空。我们将给你一些数,你需要依次插入到双端队列中。问是否存在一种操作方案,使得双端队列最后只剩下一个数。
\(1\le n\le 1000,\space \sum\limits_{i=1}^{n}a_i\le 2^{13},\space T\le 10000\),其中 \(n\gt 20\) 的数据不超过 \(150\) 组。
题解
小学生手玩 \(1s\) 可得:如果一个数被夹在两个大于它的数中间,最后队列里就至少剩下 \(3\) 个数。
也就是说,任何时刻队列一定是单峰的,峰左边的数单调递增,峰右边的数单调递减。
所以直接贪心,判断新加入的数是否 \(\le\) 队列左端的数,是则把新数加到队列左端;否则判断新加入的数是否 \(\le\) 队列右端的数,是则把新数加到队列右端;否则该局面没救了,回溯改之前的某些两可情况(即之前加入某个数时,这个数同时 \(\le\) 队列两端的数,可以加到任意一端。你可能只尝试加到了一端,现在回去改加到另一端)。
观察 \(a_i\),发现不仅都是 \(2^k\),而且总和 \(\le 2^{13}\),那是不是随便二进制状压一下两边的数,然后记忆化搜索一下就行了?
状压显然可行,因为每个数在每一边的出现次数都是 \(0\) 或 \(1\),如果出现了 \(2\) 次,由于数列单调,这两个数相邻,所以会拼成一个更大的数。而每个数直接对应一个二进制位,拼两个数根本不用任何特殊操作,直接加上新来的数就自动进位了。
然而因为有 \(1w\) 组数据,复杂度貌似不太支持把两边都状压。
考虑可不可以只状压左边,把右边用左边的状态表示出来。不难发现由于是依次加入数,我们每次加入一个数后都知道所有加入的数之和,用总和减去左边的数之和 就是右边的数之和了。
#include<bits/stdc++.h>
#define N 1010
#define M 8195
#define R sum[x]-L
using namespace std;
inline int read(){
int x=0; bool f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
if(f) return x; return 0-x;
}
int t,T,n,highbit[M],a[N],sum[N],vis[N][M]; char ans[N]; bool flag;
inline int lowbit(int x){return x&-x;}
void dfs(int x, int L){
if(highbit[R] >= highbit[L]) L+=highbit[R];
if(vis[x][L]==T) return;
vis[x][L]=T;
if(x==n){
if(L==sum[x] && L==lowbit(L)) flag=1; //两条判断是等价的,可以只取其一
return;
}
int y=x+1, l=lowbit(L), r=lowbit(R);
if(a[y]<=l) ans[y]='l', dfs(y,L+a[y]);
if(flag) return;
if(!r || a[y]<=r) ans[y]='r', dfs(y,L);
}
int main(){
t=read();
for(int i=2; i<M; ++i) highbit[i]=highbit[i>>1]+1;
for(int i=1; i<M; ++i) highbit[i]=1<<highbit[i];
for(T=1; T<=t; ++T){
n=read();
for(int i=1; i<=n; ++i) a[i]=read(), sum[i]=sum[i-1]+a[i];
flag=0;
ans[1]='l', dfs(1,a[1]);
if(!flag) printf("no\n");
else{ans[n+1]=0; printf("%s\n",ans+1);}
}
return 0;
}
【CERC 2014 E】2048的更多相关文章
- 【游戏】2048及各种变种大集合汇总【更新ing~新版Floppy2048 - 恒星聚变版 - 恶搞改数据】
threes - 鼻祖 手机版:http://asherv.com/threes/ js版:http://threesjs.com/ 2048 - 原版 http://gabrielecirulli. ...
- 【KMP】【最小表示法】NCPC 2014 H clock pictures
题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1794 题目大意: 两个无刻度的钟面,每个上面有N根针(N<=200000),每个 ...
- 【故障•监听】TNS-12518、TNS-00517和 Linux Error:32:Broken pipe
[故障|监听]TNS-12518.TNS-00517和 Linux Error:32:Broken pipe 1.1 BLOG文档结构图 1.2 前言部分 1.2.1 导读和注意事项 各位技术爱 ...
- Lenovo k860i 移植Android 4.4 cm11进度记录【上篇已完结】
2014.5.16 为了验证一下下载的CM11的源码有没有问题,决定编译一下cm官方支持的机器,手上正好有台nexus7 2012,就拿它为例测试一下在mac os x平台的整个编译过程. 1. 最开 ...
- 【机器学习Machine Learning】资料大全
昨天总结了深度学习的资料,今天把机器学习的资料也总结一下(友情提示:有些网站需要"科学上网"^_^) 推荐几本好书: 1.Pattern Recognition and Machi ...
- Web 开发人员和设计师必读文章推荐【系列三十】
<Web 前端开发精华文章推荐>2014年第9期(总第30期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- Web 开发精华文章集锦(jQuery、HTML5、CSS3)【系列二十七】
<Web 前端开发精华文章推荐>2014年第6期(总第27期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十三】
<Web 前端开发精华文章推荐>2014年第2期(总第23期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- Apple Watch PSD 源文件【免费素材下载】
Apple Watch 是苹果公司于2014年9月发布的一款智能手表.分为运动款.普通款和定制款三种,采用蓝宝石屏幕,有银色,金色,红色,绿色和白色等多种颜色可以选择.这里分享的是 Apple Wat ...
随机推荐
- iOS检测用户截屏, 并获取所截图片
// // ViewController.m // CheckScreenshotDemo // // Created by 思 彭 on 2017/4/25. // Copyright © 2017 ...
- sh脚本实战
做了什么东西还是要尽快移动到博客上,不然回头看自己写的东西已经看不懂了... 凭着回忆+搜资料,把当初写sh脚本的过程写上来. 首先新建一个.sh文件,用vim就可以 在sh的第一行,写上 #!/bi ...
- golang可见性规则(公有与私有,访问权限)
Go语言没有像其它语言一样有public.protected.private等访问控制修饰符,它是通过字母大小写来控制可见性的,如果定义的常量.变量.类型.接口.结构.函数等的名称是大写字母开头 ...
- 自定义 filter simple_tag inclusion_tag 总结
在已经注册的app下创建templatetags的python包 在包内创建py文件 my_tags.py 在py文件中写代码: from django import template registe ...
- Kinect数据
原文链接 Kinect V1 和 V2 比较 Kinect V1 和 V2 的外观比较 Kinect V1 和 V2 的参数比较 Kinect V1 和 V2 随距离增加的误差分布 Kinect V1 ...
- 【VS开发】设备控制台 (DevCon.exe) 命令
设备控制台 (DevCon.exe) 命令 DevCon (DevCon.exe) 是一个命令行工具,可以显示有关运行 Windows 的计算机上设备的详细信息.还可以使用 DevCon 启用.禁用. ...
- C++练习 | 基于栈的中缀算术表达式求值(double类型
#include<iostream> #include<stack> #include<cmath> using namespace std; char ch; b ...
- Codeforces 1229A. Marcin and Training Camp
传送门 垃圾翻译毁一生怎么办 题目看错直接 $GG$ 首先所有 $a_i$ 重复出现的人全都可以加入 考虑剩下的人发现 $a$ 必须是初始那些人的子集才能加入(证明显然),设当前考虑的人为 $x$ 则 ...
- Java并发理论简介
这些文字来自于Java程序员修炼之道,记录一下 一. java线程模型 Java线程模型建立在两个基本概念之上 共享的,默认可见的可变状态 抢占式线程调度 我们从侧面思考一下这两个概念 所有线程可以很 ...
- java中super总结
1:super 可以在子类调用父类中的成员变量(包括static修饰的变量)和方法(包括static修饰的方法) 2:super 可以调用父类的构造方法 super(参数列表),在没有定义时,并且没有 ...