P3943 星空 区间异或差分
\(\color{#0066ff}{ 题目描述 }\)
逃不掉的那一天还是来了,小 F 看着夜空发呆。
天上空荡荡的,没有一颗星星——大概是因为天上吹不散的乌云吧。
心里吹不散的乌云,就让它在那里吧,反正也没有机会去改变什么了。
小 C 拿来了一长串星型小灯泡,假装是星星,递给小 F,想让小 F 开心一点。不过,有 着强迫症的小 F 发现,这串一共 n 个灯泡的灯泡串上有 k 个灯泡没有被点亮。小 F 决定 和小 C 一起把这个灯泡串全部点亮。
不过,也许是因为过于笨拙,小 F 只能将其中连续一段的灯泡状态给翻转——点亮暗灯 泡,熄灭亮灯泡。经过摸索,小 F 发现他一共能够翻转 m 种长度的灯泡段中灯泡的状态。
小 C 和小 F 最终花了很长很长很长很长很长很长的时间把所有灯泡给全部点亮了。他 们想知道他们是不是蠢了,因此他们找到了你,让你帮忙算算:在最优的情况下,至少需要 几次操作才能把整个灯泡串给点亮?
\(\color{#0066ff}{输入格式}\)、
从标准输入中读入数据。
输入第 1 行三个正整数 n,k,m。
输入第 2 行 \(k\) 个正整数,第 i 个数表示第 i 个被没点亮的灯泡的位置 \(a_i\)
输入第 3 行 \(m\) 个正整数,第 i 个数表示第 i 种操作的长度 \(b_i\)
保证所有 \(b_i\) 互不相同;保证对于 \(1 \le i < k\),有 \(a_i< a_i+1\);保证输入数据有解。
\(\color{#0066ff}{输出格式}\)
输出标准输入中。
输出一行一个非负整数,表示最少操作次数。
\(\color{#0066ff}{输入样例}\)
5 2 2
1 5
3 4
\(\color{#0066ff}{输出样例}\)
2
\(\color{#0066ff}{数据范围与提示}\)
【样例 1 解释】

【数据范围与约定】
子任务会给出部分测试数据的特点。如果你在解决题目中遇到了困难,可以尝试只解 决一部分测试数据。
每个测试点的数据规模及特点如下表

特殊性质:保证答案小于 4
\(\color{#0066ff}{ 题解 }\)
每次区间异或,而且区间长度比较长,于是考虑差分,转为两个端点的异或
总共要翻转k个灯, 因此差分序列长度最多为2k且一定是偶数个
每次可以消除两个1,消除的代价与距离有关,现在问题转为把所有1消去的最小代价
消除的代价可以用完全背包来求,设\(v[i]\)为翻转长度为i的区间的最小代价
把每个翻转操作的长度当做两个物品x和-x,一个是影响作用\(0\to1\),一个是抵消作用\(1\to0\)
这样代价可以\(O(nm)\)的求出来
然后可以愉快的DP了,显然要状压2k的1
直接设\(f[i]\)为i到达i状态的最小代价,转移的时候,枚举两个1转移即可
总复杂度\(O(nm+4^kk^2)\)
#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int maxn = 1e5 + 10;
int n, k, m, num;
int t[maxn], v[maxn], b[maxn], f[1002020];
void dfs(int zt) {
for(int i = 1; i <= num; i++) {
if(!(zt & (1 << (i - 1)))) continue;
for(int j = i + 1; j <= num; j++) {
if(!(zt & (1 << (j - 1)))) continue;
int now = zt ^ (1 << (i - 1)) ^ (1 << (j - 1));
if(f[now] > f[zt] + v[t[j] - t[i]]) {
f[now] = f[zt] + v[t[j] - t[i]];
dfs(now);
}
}
}
}
int main() {
// freopen("starlit.in", "r", stdin);
// freopen("starlit.out", "w", stdout);
n = in(), k = in(), m = in();
int x;
for(int i = 1, ls = -1; i <= k; i++) {
x = in();
if(x == ls + 1) t[num] = x + 1;
else t[++num] = x, t[++num] = x + 1;
ls = x;
}
memset(v, 0x3f, sizeof v);
v[0] = 0;
for(int i = 1; i <= m; i++) b[i] = in();
for(int i = 1; i <= m; i++)
for(int j = b[i]; j <= n; j++)
v[j] = std::min(v[j], v[j - b[i]] + 1);
for(int i = 1; i <= m; i++)
for(int j = n - b[i]; j >= 0; j--)
v[j] = std::min(v[j], v[j + b[i]] + 1);
memset(f, 0x3f, sizeof f);
f[(1 << num) - 1] = 0;
dfs((1 << num) - 1);
printf("%d", f[0]);
return 0;
}
P3943 星空 区间异或差分的更多相关文章
- 洛谷P3943 星空
洛谷P3943 星空 题目背景 命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷. 你来过,然后你走后,只留下星空. 题目描述 逃不掉的那一天还是来了,小 F 看着夜空发呆. 天上空荡荡的,没有一颗 ...
- [洛谷P3943]:星空(DP+最短路)
题目传送门 题目背景 命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷.你来过,然后你走后,只留下星空. 题目描述 逃不掉的那一天还是来了,小$F$看着夜空发呆.天上空荡荡的,没有一颗星星——大概是 ...
- P5057 [CQOI2006]简单题 前缀异或差分/树状数组
好思路,好思路... 思路:前缀异或差分 提交:1次 题解:区间修改,单点查询,树状数组,如思路$qwq$ #include<cstdio> #include<iostream> ...
- Consecutive Sum LightOJ - 1269(区间异或和)
Consecutive Sum 又来水一发blog... 本来是昨天补codechef的题,最后一道题是可持久化字典树,然后去黄学长博客看了看 觉得字典树写法有点不太一样,就想着用黄学长的板子写码几道 ...
- BZOJ 4260 Codechef REBXOR (区间异或和最值) (01字典树+DP)
<题目链接> 题目大意:给定一个序列,现在求出两段不相交的区间异或和的最大值. 解题分析: 区间异或问题首先想到01字典树.利用前缀.后缀建树,并且利用异或的性质,相同的两个数异或变成0, ...
- CF 617E【莫队求区间异或和】
E. XOR and Favorite Number time limit per test 4 seconds memory limit per test 256 megabytes input s ...
- bzoj 2819 Nim dfn序+树状数组维护区间异或值
题目大意 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...
- 计蒜客 39272.Tree-树链剖分(点权)+带修改区间异或和 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest E.) 2019ICPC西安邀请赛现场赛重现赛
Tree Ming and Hong are playing a simple game called nim game. They have nn piles of stones numbered ...
- BZOJ 4017 小 Q 的无敌异或 ( 树状数组、区间异或和、区间异或和之和、按位计贡献思想 )
题目链接 题意 : 中文题 分析 : 首先引入两篇写的很好的题解 题解一.题解二 听说这种和异或相关区间求和的问题都尽量按位考虑 首先第一问.按二进制位计贡献的话.那么对于第 k 位而言 其贡献 = ...
随机推荐
- Http工作过程
一次HTTP操作称为一个事务,其工作整个过程如下: 1 ) .地址解析, 如用客户端浏览器请求这个页面:http://localhost.com:8080/index.htm 从中分解出协议名.主机名 ...
- 第八课 go的条件语句
1 if ... else package main import "fmt" func main() { flag:= { fmt.Println("flag > ...
- 人脑和CPU
人类的数学运算没有计算机快是因为神经信号速度没有电信号快吗,电信号是光速吧. 不过人类的cpu大脑和存储硬盘和内存超过目前计算机n条街,虽然传输速度慢,但是传输量也是大的,其实计算机就是根据人脑设计的 ...
- Python函数(六)-嵌套函数
嵌套函数就是在一个函数里再嵌套一个或多个函数 # -*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" def First(): pri ...
- 我的第一个Socket程序-SuperSocket使用入门(二)
操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操操 辛辛苦苦写那么久的博客,最后手贱点了全屏富文本编辑器 ...
- Eclipse 快键键(持续更新)
本人抛弃一些简单常见的快键键,例如 ctrl+c ,+v ,+z之类的 1.ctrl+d 删除一整行 2.ctrl+f 搜索 3.光标选中几行,ctrl+alt+↓ 向下复制选中的那几行 4.光标 ...
- 复选框操作checked选中为true,反之为False,也可以赋值为true,false
- C++面向对象类的实例题目六
问题描述: 编写一个程序计算两个给定长方形的面积,其中在设计类成员函数addarea()(用于计算两个长方形的总面积)时使用对象作为参数. 程序代码: #include<iostream> ...
- Windows系统 为 QT5软件 搭建 OpenCV2 开发环境
Windows系统 为 QT5软件 搭建 OpenCV2 开发环境 我们的电脑系统:Windows 10 64位 Qt5 软件:Qt 5. 7. 0 OpenCV2 版本:OpenCV2.4.10 1 ...
- ROS Learning-002 beginner_Tutorials 如何添加ROS环境变量 和 如何更新ROS源代码
ROS Indigo beginner_Tutorials 之 添加环境变量 和 更新ROS源代码的命令 我使用的虚拟机软件:VMware Workstation 11 使用的Ubuntu系统:Ubu ...