题意

  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的更多相关文章

  1. 【游戏】2048及各种变种大集合汇总【更新ing~新版Floppy2048 - 恒星聚变版 - 恶搞改数据】

    threes - 鼻祖 手机版:http://asherv.com/threes/ js版:http://threesjs.com/ 2048 - 原版 http://gabrielecirulli. ...

  2. 【KMP】【最小表示法】NCPC 2014 H clock pictures

    题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1794 题目大意: 两个无刻度的钟面,每个上面有N根针(N<=200000),每个 ...

  3. 【故障•监听】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  导读和注意事项 各位技术爱 ...

  4. Lenovo k860i 移植Android 4.4 cm11进度记录【上篇已完结】

    2014.5.16 为了验证一下下载的CM11的源码有没有问题,决定编译一下cm官方支持的机器,手上正好有台nexus7 2012,就拿它为例测试一下在mac os x平台的整个编译过程. 1. 最开 ...

  5. 【机器学习Machine Learning】资料大全

    昨天总结了深度学习的资料,今天把机器学习的资料也总结一下(友情提示:有些网站需要"科学上网"^_^) 推荐几本好书: 1.Pattern Recognition and Machi ...

  6. Web 开发人员和设计师必读文章推荐【系列三十】

    <Web 前端开发精华文章推荐>2014年第9期(总第30期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  7. Web 开发精华文章集锦(jQuery、HTML5、CSS3)【系列二十七】

    <Web 前端开发精华文章推荐>2014年第6期(总第27期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  8. Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十三】

    <Web 前端开发精华文章推荐>2014年第2期(总第23期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  9. Apple Watch PSD 源文件【免费素材下载】

    Apple Watch 是苹果公司于2014年9月发布的一款智能手表.分为运动款.普通款和定制款三种,采用蓝宝石屏幕,有银色,金色,红色,绿色和白色等多种颜色可以选择.这里分享的是 Apple Wat ...

随机推荐

  1. iOS检测用户截屏, 并获取所截图片

    // // ViewController.m // CheckScreenshotDemo // // Created by 思 彭 on 2017/4/25. // Copyright © 2017 ...

  2. sh脚本实战

    做了什么东西还是要尽快移动到博客上,不然回头看自己写的东西已经看不懂了... 凭着回忆+搜资料,把当初写sh脚本的过程写上来. 首先新建一个.sh文件,用vim就可以 在sh的第一行,写上 #!/bi ...

  3. golang可见性规则(公有与私有,访问权限)

       Go语言没有像其它语言一样有public.protected.private等访问控制修饰符,它是通过字母大小写来控制可见性的,如果定义的常量.变量.类型.接口.结构.函数等的名称是大写字母开头 ...

  4. 自定义 filter simple_tag inclusion_tag 总结

    在已经注册的app下创建templatetags的python包 在包内创建py文件 my_tags.py 在py文件中写代码: from django import template registe ...

  5. Kinect数据

    原文链接 Kinect V1 和 V2 比较 Kinect V1 和 V2 的外观比较 Kinect V1 和 V2 的参数比较 Kinect V1 和 V2 随距离增加的误差分布 Kinect V1 ...

  6. 【VS开发】设备控制台 (DevCon.exe) 命令

    设备控制台 (DevCon.exe) 命令 DevCon (DevCon.exe) 是一个命令行工具,可以显示有关运行 Windows 的计算机上设备的详细信息.还可以使用 DevCon 启用.禁用. ...

  7. C++练习 | 基于栈的中缀算术表达式求值(double类型

    #include<iostream> #include<stack> #include<cmath> using namespace std; char ch; b ...

  8. Codeforces 1229A. Marcin and Training Camp

    传送门 垃圾翻译毁一生怎么办 题目看错直接 $GG$ 首先所有 $a_i$ 重复出现的人全都可以加入 考虑剩下的人发现 $a$ 必须是初始那些人的子集才能加入(证明显然),设当前考虑的人为 $x$ 则 ...

  9. Java并发理论简介

    这些文字来自于Java程序员修炼之道,记录一下 一. java线程模型 Java线程模型建立在两个基本概念之上 共享的,默认可见的可变状态 抢占式线程调度 我们从侧面思考一下这两个概念 所有线程可以很 ...

  10. java中super总结

    1:super 可以在子类调用父类中的成员变量(包括static修饰的变量)和方法(包括static修饰的方法) 2:super 可以调用父类的构造方法 super(参数列表),在没有定义时,并且没有 ...