【BZOJ3508】开灯

题面

bzoj

题解

其实变为目标操作和从目标操作变回来没有区别,我们考虑从目标操作变回来。

区间整体翻转(\(\text{Xor}\;1\))有点难受,我们考虑将这个操作放在差分数组上,也就是说令\(a\)为原数组,\(c\)为差分数组,\(c_i=a_{i-1}\text{Xor}\;a_i\)。

那么我们就相当于让差分数组上的数全变为\(0\),而一次操作就相当于让一对\(1\)消掉或一对\(0,1\)位置互换。

而两个\(1\)在其他位置消掉和在某个\(1\)的位置消掉是没有区别的,多个\(1\)也一样,所以我们可以直接\(bfs\)预处理每对点消掉的贡献。

而差分数组最多\(2K\)个\(1\),状压每个点有没有被消掉即可。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std; inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (ch != '-' && (ch > '9' || ch < '0')) ch = getchar();
if (ch == '-') w = -1 , ch = getchar();
while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
return w * data;
}
const int INF = 0x3f3f3f3f;
const int MAX_N = 40005, MAX_M = 105;
int N, K, M;
int b[MAX_M];
bool used[MAX_N], g[MAX_N];
int st[30], tp;
int cost[30][30], dep[MAX_N]; queue<int> que;
void bfs(int s, int *dis) {
memset(dep, 0, sizeof(dep));
dep[s] = 1;
que.push(s);
while (!que.empty()) {
int x = que.front(); que.pop();
for (int i = 1; i <= M; i++) {
if (x + b[i] <= N && !dep[x + b[i]]) dep[x + b[i]] = dep[x] + 1, que.push(x + b[i]);
if (x - b[i] >= 1 && !dep[x - b[i]]) dep[x - b[i]] = dep[x] + 1, que.push(x - b[i]);
}
}
for (int i = 0; i < tp; i++) dis[i] = dep[st[i]] - 1;
}
int f[1 << 20];
int main () {
#ifndef ONLINE_JUDGE
freopen("cpp.in", "r", stdin);
#endif
int Q = gi();
while (Q--) {
memset(used, 0, sizeof(used)); tp = 0;
N = gi() + 1, K = gi(), M = gi();
for (int i = 1; i <= K; i++) used[gi()] = 1;
for (int i = 1; i <= M; i++) b[i] = gi();
for (int i = 1; i <= N; i++) g[i] = used[i] ^ used[i - 1];
for (int i = 1; i <= N; i++) if (g[i]) st[tp++] = i;
for (int i = 0; i < tp; i++) bfs(st[i], cost[i]);
memset(f, 0x3f, sizeof(f));
f[0] = 0;
for (int S = 0; S < (1 << tp) - 1; S++) {
for (int i = 0; i < tp; i++) {
if (S >> i & 1) continue;
for (int x = i + 1; x < tp; x++) {
if ((S >> x & 1) == 0 && (cost[i][x] != -1)) {
int tmp = (S | (1 << i) | (1 << x));
f[tmp] = min(f[tmp], f[S] + cost[i][x]);
}
}
break;
}
}
printf("%d\n", f[(1 << tp) - 1] == INF ? -1 : f[(1 << tp) - 1]);
}
return 0;
}

【BZOJ3508】开灯的更多相关文章

  1. BZOJ3508 开灯 & [校内NOIP2018模拟20181027] 密码锁

    Time Limit: 10 Sec Memory Limit: 128 MB Description xx作为信息学界的大神,拥有众多的粉丝.为了感谢众粉丝的爱戴,xx决定举办一场晚会.为了气派,x ...

  2. bzoj3508: 开灯

    题目链接 题解 设\(b[i]=a[i]\ xor\ a[i+1]\) 我们可以发现,修改只会改变\(b[l-1]\)和\(b[r]\) 然后发现\(b[i]=1\)的点最多\(2*k\)个 状压\( ...

  3. c语言实现开灯问题

    开灯问题: 有n盏灯,编号为1~n,第1个人把所有灯打开,第2个人按下所有编号为2 的倍数的开关(这些灯将被关掉),第3 个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),依 ...

  4. Jquery开灯关灯效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 9509 开灯(dfs)

    9509 开灯 时间限制:1000MS  内存限制:65535K提交次数:0 通过次数:0 题型: 编程题   语言: G++;GCC Description 有16的开关分别控制16盏灯,开关排列成 ...

  6. NYOJ 题目77 开灯问题(简单模拟)

    开灯问题 时间限制:3000 ms  |            内存限制:65535 KB 难度:1           描述 有n盏灯,编号为1~n,第1个人把所有灯打开,第2个人按下所有编号为2 ...

  7. 洛谷 P1876 开灯(思维,枚举,规律题)

    P1876 开灯 题目背景 该题的题目是不是感到很眼熟呢? 事实上,如果你懂的方法,该题的代码简直不能再短. 但是如果你不懂得呢?那...(自己去想) 题目描述 首先所有的灯都是关的(注意是关!),编 ...

  8. 【Luogu1876】开灯(数论)

    [Luogu1876]开灯(数论) 题面 题目描述 首先所有的灯都是关的(注意是关!),编号为1的人走过来,把是一的倍数的灯全部打开,编号为二的的把是二的倍数的灯全部关上,编号为3的人又把是三的倍数的 ...

  9. POJ 1218 THE DRUNK JAILER(类开灯问题,完全平方数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2188 题目大意:n为5-100之间的一个数,代表有多少间牢房,刚开始所有房间打开,第一轮2的倍数的房间 ...

随机推荐

  1. 安装Office 2016 出现 Office 16 Click-to-Run Extensibility Component

    无法安装 64 位版本的 Office,因为在您的 PC 上找到了以下 32 位程序: Office 16 Click-to-Run Extensibility Component 请卸载所有 32 ...

  2. [转帖]linux基础知识大纲

    linux基础知识大纲 https://blog.csdn.net/CSDN___LYY/article/details/80810403 1.Linux操作系统概述Linux操作系统的发展过程.创始 ...

  3. [Python学习笔记-007] 使用PyEnchant检查英文单词

    最近在教儿子做自然拼读,跟他玩了一个单词游戏,就是利用简单的枚举找出适合小朋友学习的两个字母的单词.人工找寻难免有疏漏之处,这里使用PyEnchant给出一个简单的脚本. 01 - foo.py #! ...

  4. windows版mysql8.0安装详解

    2018年07月04日 13:37:40 Zn昕 阅读数 6433更多 分类专栏: mysql   版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. ...

  5. 百度前端技术学院task1 总结

    1.居中:当使用text-align或者vatical-align无法达到居中的时候,如果知道元素的大小,可以采用先设为left或right为50%,再设置margin-left或者margin-ri ...

  6. Redis(五)事务

    Redis(五)事务 引用wiki中关于事务处理的定义: Transaction processing is information processing in computer science th ...

  7. Go语言-1-标识符与变量

    目录 1. Go标识符 1.1 Go关键字 1.2 常量标识符(4个) 1.3 空白标识符(1个) 1.4 内置数据类型标识符 1.5 内置函数(15个) 2. Go语言操作符 3. Go语言变量 3 ...

  8. Python 查看模块的帮助文档,方法和帮助信息

    参考链接:https://blog.csdn.net/u013810296/article/details/55509284 这里介绍下python自带的查看帮助功能,可以在编程时不中断地迅速找到所需 ...

  9. EurekaClient自动装配及启动流程解析

    在上篇文章中,我们简单介绍了EurekaServer自动装配及启动流程解析,本篇文章则继续研究EurekaClient的相关代码 老规矩,先看spring.factories文件,其中引入了一个配置类 ...

  10. Delphi中窗体的事件

    Delphi中窗体的事件 Form窗体可以响应各种各样的时间,在Object Inspector的Events页面中罗列了一大堆,如下图: 下面将要列出一些常用的事件. 1.OnActivate 当窗 ...