UVALive 6931 Can't stop playing (Regionals 2014 >> Europe - Central)
题目
一开始有一个双头队列,每次添加一个数(这是数是二的幂,所有数的和不大于\(2^13\)),由你来决定添加到队头还是队尾。如果队列里面相邻的两个数相同,设它们都是\(x\),那么这两个数会合并为\(2x\)。问所有数添加完后队列里能否只剩下一个数。
算法
搜索题,但是需要巧妙地记录状态!这种题不可多。
一个显然的是,队列里不会存在相邻的三个数\(a,b,c\),满足\(a>b,c>b\)。这样的话,队列肯定是一个倒V字。
记状态\((i,j)\)为添加完前\(i\)个数,\(j\)是倒V左半边的上升序列状态,\(j\)最大是\(2^{13}\)。通过这两个,我们可以算出倒V右半边的序列状态!
这样的话,时间复杂度就是\(O(n 2^{13})\)。
代码
官方的标程有点点小错误。UVALive上的数据也错了。但当时比赛的数据是正确的!
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <vector>
#include <assert.h>
using namespace std;
template <class T>
void tension(T &a, const T &b) {
if (b < a) a = b;
}
template <class T>
void relax(T &a, const T &b) {
if (b > a) a = b;
}
typedef long long i64;
#ifndef ONLINE_JUDGE
#define ep(...) fprintf(stderr, __VA_ARGS__)
#else
#define ep(...) assert(true)
#endif
int n;
int sum[1003], A[1003];
bool vis[1003][(1 << 13) + 1];
char ans[1003];
int highBit[1 << 14];
int place(int a, int b, int x) {
if (highBit[a] > highBit[b]) {
int tmp = highBit[a];
a -= tmp;
b += tmp;
}
if (a && (a & -a) < x) return -1;
a += x;
while (highBit[a] == highBit[b]) {
int tmp = highBit[a];
a += tmp;
b -= tmp;
}
return a;
}
bool dfs(int k, int s1) {
int s2 = (k ? sum[k - 1] : 0) - s1;
if (k == n) {
if (highBit[s1] > highBit[s2]) {
int tmp = highBit[s1];
s1 -= tmp;
s2 += tmp;
}
if (highBit[s2] > highBit[s1]) {
int tmp = highBit[s2];
s2 -= tmp;
s1 += tmp;
}
if (s1 == (s1 & -s1) && s2 == 0) return true;
if (s2 == (s2 & -s2) && s1 == 0) return true;
return false;
}
if (vis[k][s1]) return false;
vis[k][s1] = true;
int x = A[k];
int tmp = place(s1, s2, x);
if (tmp != -1 && dfs(k + 1, tmp)) {
//ep("l (%d, %d) %d ->\n", s1, s2, x);
ans[k] = 'l';
return true;
}
tmp = place(s2, s1, x);
if (tmp != -1 && dfs(k + 1, sum[k] - tmp)) {
//ep("r (%d, %d) %d ->\n", s1, s2, x);
ans[k] = 'r';
return true;
}
return false;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
//freopen("all.in", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
for (int i = 1; i < 1 << 14; i ++)
if ((i & -i) == i) highBit[i] = i;
else highBit[i] = highBit[i - 1];
scanf("%*d");
for (int cases = 1; scanf("%d", &n) == 1; cases ++) {
//ep("Case %d: ", cases);
for (int i = 0; i < n; i ++) {
scanf("%d", A + i);
sum[i] = A[i];
if (i) sum[i] += sum[i - 1];
}
//memset(vis, 0, sizeof vis);
for (int i = 0; i < n; i ++)
memset(vis[i], 0, sizeof vis[i]);
if (dfs(0, 0)) {
ans[n] = '\0';
printf("%s\n", ans);
}
else printf("no\n");
}
return 0;
}
UVALive 6931 Can't stop playing (Regionals 2014 >> Europe - Central)的更多相关文章
- UVALive 6584 Escape (Regionals 2013 >> Europe - Central)
题目 给出一棵树,每个节点有一个怪物或血药,遇到怪物必须打,打完后扣掉一定的血量. 一开始英雄的血量为\(0\),当血量小于\(0\)时就挂了. 给出英雄的起点和终点,问能否成功到达终点. 算法 这题 ...
- Regionals 2014 >> Asia - Taichung 7003 - A Balance Game on Trees 树形DP + 二维费用背包
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
- UVALive 5545 Glass Beads
Glass Beads Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Origin ...
- UVALive 2664 One-way traffic
One-way traffic Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Or ...
- UVALive 2957 Bring Them There
Bring Them There Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. O ...
- UVALive 3989 Ladies' Choice
Ladies' Choice Time Limit: 6000ms Memory Limit: 131072KB This problem will be judged on UVALive. Ori ...
- UVALive 5583 Dividing coins
Dividing coins Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Ori ...
- UVALive 5292 Critical Links
Critical Links Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Ori ...
- BNU 33693——Problemsetting——————【枚举+最大流】
Problemsetting Time Limit: 5000ms Memory Limit: 131072KB 64-bit integer IO format: %lld Java cl ...
随机推荐
- tomcat配置没啥难的啊
总体上就是: 1.下载jdk并安装. 2.下载tomcat 3.分别设置好环境变量. 4.cmd java -version 如果成功,证明java jdk配置OK startup.bat 如果成功 ...
- 【转】从底层了解ASP.NET体系结构
从底层了解ASP.NET体系结构 原文:http://blog.csdn.net/zhoufoxcn/article/details/1890158 Java体系架构的书多如牛毛,比如SSH架构什么的 ...
- 转: seajs手册与文档之 -- require规则
require 规则 正确拼写 不要修改 使用直接量 动态依赖的小提示 书写规则 使用 SeaJS 书写模块代码时,需要遵循一些简单规则: 1. 正确拼写 在模块代码中,第一个参数 必须 命名为 re ...
- BZOJ 1015
program bzoj1015; {$inline on} ; type node=record togo,next:longint; end; var tot,n,m,d,cnt:longint; ...
- 九度 和为S的连续正数序列
题目1354:和为S的连续正数序列 时间限制:2 秒 内存限制:32 兆 特殊判题:否 提交:2008 解决:622 题目描述: 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上 ...
- POJ 1692 Crossed Matchings(DP)
Description There are two rows of positive integer numbers. We can draw one line segment between any ...
- 写了交互给后台后来不能用?bug多多多又找不到文件效率低?工作流程帮你优化起来~~~~
前端工作流程(多方交互篇) 新的网页: 1.跟美工沟通,跟产品沟通,跟后台沟通.前两者主要是页面样式.后者主要是表单交互.用哪个框架之类的. 2.实现.(写清楚哪块是用什么验证方式的)→ 给后台. 3 ...
- 【Hibernate】Illegal attempt to associate a collection with two open sessions
今天在用Hibernate对对象进行修改操作的时候报了这个错. 之前一直没什么错误,但是今天修改了一下表结构,增加了一个OneToMany的映射. 所以在我获取对象,重新set一个变量之后就报了这个错 ...
- 数矩形(N - 暴力求解、打表)
数矩形 Description 给你一个高为n ,宽为m列的网格,计算出这个网格中有多少个矩形,下图为高为2,宽为4的网格. Input 第一行输入一个t, 表示有t组数据,然后 ...
- Fragment实现不支持左右滑动的Tab
主要思想:顶部标题top.xml,中间Fragment,底部Tab导航. top.xml具体实现: <?xml version="1.0" encoding="ut ...