[洛谷P3943]:星空(DP+最短路)
题目传送门
题目背景
命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷。
你来过,然后你走后,只留下星空。
题目描述
逃不掉的那一天还是来了,小$F$看着夜空发呆。
天上空荡荡的,没有一颗星星——大概是因为天上吹不散的乌云吧。
心里吹不散的乌云,就让它在那里吧,反正也没有机会去改变什么了。
小$C$拿来了一长串星型小灯泡,假装是星星,递给小$F$,想让小$F$开心一点。不过,有着强迫症的小$F$发现,这串一共$n$个灯泡的灯泡串上有$k$个灯泡没有被点亮。小$F$决定和小$C$一起把这个灯泡串全部点亮。
不过,也许是因为过于笨拙,小$F$只能将其中连续一段的灯泡状态给翻转——点亮暗灯泡,熄灭亮灯泡。经过摸索,小$F$发现他一共能够翻转$m$种长度的灯泡段中灯泡的状态。
小$C$和小$F$最终花了很长很长很长很长很长很长的时间把所有灯泡给全部点亮了。他们想知道他们是不是蠢了,因此他们找到了你,让你帮忙算算:在最优的情况下,至少需要几次操作才能把整个灯泡串给点亮?
输入格式
从标准输入中读入数据。
输入第$1$行三个正整数$n,k,m$。
输入第$2$行$k$个正整数,第$i$个数表示第$i$个被没点亮的灯泡的位置$a_i$。
输入第$3$行$m$个正整数,第$i$个数表示第$i$种操作的长度$b_i$。
输出格式
输出标准输入中。
输出一行一个非负整数,表示最少操作次数。
样例
样例输入
5 2 2
1 5
3 4
样例输出
2
数据范围与提示
样例解释:

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

特殊性质:保证答案小于$4$。
题解
发现$k$很小。
那么我们考虑转化这个问题,利用状压$DP$。
再想区间修改,离线,那么用差分,也就是异或差分。
问题转化为:
给定一个长度为$n$的$0/1$串,其中只有不超过$2k$个$0$。
每次操作是,从给定的$m$种距离中选择一种,选择序列上相距这个距离的两个位同时取反。
求至少需要操作多少次才能使得整个串全为$1$。
如果某个地方有$0$,那么这个位置一定会进行操作来消去这个$0$。
我们假定每次我们都选含$0$的来进行操作:
一个$1$一个$0$:可以视作移动;
两个$0$:看作将其中一个$0$移到另一个$0$的位置,随后它们均消去。
发现又可以转化问题:
给定一个有$n$个点的图,其中之后不超过$2k$个点存在物品。
每次操作时,从给定的$m$种距离中选择一种,选择序列上一个物品进行移动;两个物品碰到一起会消去。
求至少需要操作多少次才能使得所有物品消失。
消去的两个物品可以看作是其中一个移动到了另外一个物品的位置,代价即为从一个物品到另一个物品所需要的最小步数;
我们发现,这种移动只有$2k$个起点;
同时,图上$n$个点每个点有$m$条边;
因此,预处理两两之间所需要的最短步数可以使用$\Theta(n\times m\times k)$的$BFS$
最后一次转化问题:
有$2k$个物品,选择其中两个消去,分别有不同的代价,求使得所有物品消失的最小代价。
状压$DP$轻松解决。
时间复杂度:$\Theta(n\times m\times k+k\times 2^{2k})$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
int n,k,m;
bool a[40001];
int b[100];
int dis[20][40001];
int dp[300000];
int cnt;
pair<int,int> p[20];
queue<int> q;
void bfs(pair<int,int> x)
{
dis[x.first][x.second]=0;
q.push(x.second);
while(q.size())
{
int flag=q.front();
q.pop();
for(int i=1;i<=m;i++)
{
if(flag-b[i]>=0&&dis[x.first][flag-b[i]]>dis[x.first][flag]+1)
{
dis[x.first][flag-b[i]]=dis[x.first][flag]+1;
q.push(flag-b[i]);
}
if(flag+b[i]<=n&&dis[x.first][flag+b[i]]>dis[x.first][flag]+1)
{
dis[x.first][flag+b[i]]=dis[x.first][flag]+1;
q.push(flag+b[i]);
}
}
}
}
int getans(int x)
{
if(dp[x]!=-1)return dp[x];
if(!x)return x;
int res=1<<30;
int flag=0;
while(!(x&(1<<flag)))flag++;
for(int i=flag+1;i<=2*k;i++)
if(x&(1<<i))res=min(res,getans(x^(1<<flag)^(1<<i))+dis[flag][p[i].second]);
dp[x]=res;
return res;
}
int main()
{
memset(dis,0x3f,sizeof(dis));
memset(dp,-1,sizeof(dp));
scanf("%d%d%d",&n,&k,&m);
for(int i=1;i<=k;i++)
{
int x;
scanf("%d",&x);
a[x]=1;
}
for(int i=1;i<=m;i++)
scanf("%d",&b[i]);
for(int i=0;i<=n;i++)
if(a[i]!=a[i+1])
p[cnt]=make_pair(cnt++,i);
for(int i=0;i<cnt;i++)
bfs(p[i]);
cout<<getans((1<<cnt)-1);
return 0;
}
rp++
[洛谷P3943]:星空(DP+最短路)的更多相关文章
- 洛谷P3943 星空
洛谷P3943 星空 题目背景 命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷. 你来过,然后你走后,只留下星空. 题目描述 逃不掉的那一天还是来了,小 F 看着夜空发呆. 天上空荡荡的,没有一颗 ...
- 洛谷 P3943 星空
题目背景 命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷. 你来过,然后你走后,只留下星空. 题目描述 逃不掉的那一天还是来了,小 F 看着夜空发呆. 天上空荡荡的,没有一颗星星——大概是因为天上 ...
- 洛谷P3943 星空——题解
一道很好的锻炼思维难度的题,如果您能在考场上直接想出来的话,提高组450分以上就没问题了吧.(别像作者一样看了好几篇题解才勉强会) 先提取出题目大意:给定一个长度n<=40000的01串,其中1 ...
- 洛谷P3943星空
啦啦啦啦——又是五月天的歌,题目传送门 这道题比之前两道真的不是同一级别的,这里我这个蒟蒻也讲不清,不如看下这位大佬的吧,他的写的已经非常清楚了:Z-Y-Y-S,这里我就只放下我的代码,也是按照这位大 ...
- CodeForces 79D 【Password】,洛谷P3943 【星空】
其实我做的是洛谷的P3943,但是听说fstqwq窃题...... 题目描述: 小 C 拿来了一长串星型小灯泡,假装是星星,递给小 F,想让小 F 开心一点.不过,有 着强迫症的小 F 发现,这串一共 ...
- 洛谷教主花园dp
洛谷-教主的花园-动态规划 题目描述 教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都不一样,一些树可能会因为不适合这个位置的土壤而损失观赏价 ...
- 洛谷 p6858 深海少女与胖头鱼 洛谷月赛 期望dp
洛谷10月月赛 2 t2 深海少女与胖头鱼 题目链接 参考资料:洛谷10月赛2讲评ppt; 本篇题解考完那天就开始写,断断续续写到今天才写完 本题作为基础的期望dp题,用来学习期望dp还是很不错的 ( ...
- 洛谷P4719 动态dp
动态DP其实挺简单一个东西. 把DP值的定义改成去掉重儿子之后的DP值. 重链上的答案就用线段树/lct维护,维护子段/矩阵都可以.其实本质上差不多... 修改的时候在log个线段树上修改.轻儿子所在 ...
- 2018普及组摆渡车洛谷5017(dp做法)
啦啦啦,这一篇是接上一篇的博客,上一篇是记忆化搜索,而这一篇是dp+前缀和小技巧 dp这种玄学做法我这种蒟蒻当然不是自己想出来的,参考https://blog.csdn.net/kkkksc03/ar ...
随机推荐
- KETTLE——(三)数据输出
数据输出和数据输入基本差不多,KETTLE本身支持的数据输出方式也特别多,还是以数据库输出为例. 打开表输出的界面,简单介绍一下其功能: 就这个界面,如果不勾选[指定数据库字段],KETTLE ...
- Visual Studio格式化所有文档
1.下载 Format All Files 2. 格式化指定类型的文件 说明: Enable Remove and Sort Usings:移除未使用过的引用+排序引用 Exclusion Patte ...
- clinical-逻辑核查数据的操作
1. 前端页面样式 2. 前端代码 添加: 展示: 修改 删除 3. 后台代码 封装的DAO类数据 # coding: utf-8 from pdform.services.db.dbCore imp ...
- Java 之 回调方法
打个比方,我们点外卖都有到达提醒的服务,顾客自己选择提醒的方式.可以是电话提醒.短信提醒.也可以敲门提醒,这里,“提醒”这个行为是美团或饿了么这样的平台提供的,相当于库函数,但是提醒的方式是由顾客决定 ...
- SVN检出新项目
1.新建文件夹SourseCode -->打开SourseCode文件夹,右键空白处 ---> 选择SVN Checkout --选择URL of repository,选择Checkou ...
- C/C++ 引入头文件时 #include<***.h> 与 #include"***.h" 区别
两种情况区分: 1.#include <> 编译器只会去系统文件目录中查找,找不到就报错. 2.#include " " 编译器会先在用户目录中查找,再到编译器设定的 ...
- [APIO 2010] [LOJ 3144] 奇怪装置 (数学)
[APIO 2010] [LOJ 3144] 奇怪装置 (数学) 题面 略 分析 考虑t1,t2时刻坐标相同的条件 \[\begin{cases} t_1+\lfloor \frac{t_1}{B} ...
- JS—图片压缩上传(单张)
*vue+webpack环境,这里的that指到vue实例 <input type="file" name="file" accept="ima ...
- Django中用 form 实现登录注册
1.forms模块 将Models和Forms结合到一起使用,将Forms中的类和Models中的类关联到一起,实现属性的共享 1.在forms.py中创建class,继承自forms.ModelFo ...
- JavaScript、ES6中的类和对象
面向对象可以用于描述现实世界的事物,但是事物分为具体的(特指的)事物和抽象的(泛指的)事物. 面向对象思维的特点: 1.抽取(抽象)对象共有的属性和行为组织(封装)成一个类(模板) 2. ...