题目传送门


题目背景

命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷。
你来过,然后你走后,只留下星空。


题目描述

逃不掉的那一天还是来了,小$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+最短路)的更多相关文章

  1. 洛谷P3943 星空

    洛谷P3943 星空 题目背景 命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷. 你来过,然后你走后,只留下星空. 题目描述 逃不掉的那一天还是来了,小 F 看着夜空发呆. 天上空荡荡的,没有一颗 ...

  2. 洛谷 P3943 星空

    题目背景 命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷. 你来过,然后你走后,只留下星空. 题目描述 逃不掉的那一天还是来了,小 F 看着夜空发呆. 天上空荡荡的,没有一颗星星——大概是因为天上 ...

  3. 洛谷P3943 星空——题解

    一道很好的锻炼思维难度的题,如果您能在考场上直接想出来的话,提高组450分以上就没问题了吧.(别像作者一样看了好几篇题解才勉强会) 先提取出题目大意:给定一个长度n<=40000的01串,其中1 ...

  4. 洛谷P3943星空

    啦啦啦啦——又是五月天的歌,题目传送门 这道题比之前两道真的不是同一级别的,这里我这个蒟蒻也讲不清,不如看下这位大佬的吧,他的写的已经非常清楚了:Z-Y-Y-S,这里我就只放下我的代码,也是按照这位大 ...

  5. CodeForces 79D 【Password】,洛谷P3943 【星空】

    其实我做的是洛谷的P3943,但是听说fstqwq窃题...... 题目描述: 小 C 拿来了一长串星型小灯泡,假装是星星,递给小 F,想让小 F 开心一点.不过,有 着强迫症的小 F 发现,这串一共 ...

  6. 洛谷教主花园dp

    洛谷-教主的花园-动态规划   题目描述 教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都不一样,一些树可能会因为不适合这个位置的土壤而损失观赏价 ...

  7. 洛谷 p6858 深海少女与胖头鱼 洛谷月赛 期望dp

    洛谷10月月赛 2 t2 深海少女与胖头鱼 题目链接 参考资料:洛谷10月赛2讲评ppt; 本篇题解考完那天就开始写,断断续续写到今天才写完 本题作为基础的期望dp题,用来学习期望dp还是很不错的 ( ...

  8. 洛谷P4719 动态dp

    动态DP其实挺简单一个东西. 把DP值的定义改成去掉重儿子之后的DP值. 重链上的答案就用线段树/lct维护,维护子段/矩阵都可以.其实本质上差不多... 修改的时候在log个线段树上修改.轻儿子所在 ...

  9. 2018普及组摆渡车洛谷5017(dp做法)

    啦啦啦,这一篇是接上一篇的博客,上一篇是记忆化搜索,而这一篇是dp+前缀和小技巧 dp这种玄学做法我这种蒟蒻当然不是自己想出来的,参考https://blog.csdn.net/kkkksc03/ar ...

随机推荐

  1. lateral view 使用方法

    这个函数相当于拆开行变成列. 可以理解为行转列. select id,order_label from table_bx lateral view explode(split(work_order_l ...

  2. Ora01653 :是表空间不足

    解决方案:表空间中增加数据文件: ALTER TABLESPACE 表空间名称ADD DATAFILE 'D:\app\Administrator\oradata\orcl\Ibomis1.dbf' ...

  3. sqluldr2 oracle直接导出数据为文本的小工具使用

    近期客户有需求,导出某些审计数据,供审计人进行核查,只能导出成文本或excel格式的进行查看,这里我们使用sqluldr2工具进行相关数据的导出. oracle导出数据为文本格式比较麻烦,sqluld ...

  4. oracle--序列&视图&索引&视图&可视化操作&分页&数据库备份

    --oracle学习内容--oracle的管理系统学习--oracle的数据管理学习--oracle的用户管理--oracle二维表管理--oracle的其他知识 --oracle的序列.视图.索引 ...

  5. Git-第一篇认识git,核心对象,常用命令

    1.git一般使用流程 4大核心对象:工作区.暂存区.本地库.远端库. 2.常用命令 1>git init:初始化本地仓库 2>git clone:克隆仓库到指定地方 3>git a ...

  6. 第021讲:函数:lambda表达式

    0. 请使用lambda表达式将下边函数转变为匿名函数? def fun_A(x, y=): return x * y me:lambda x,y=3:x*y 1.请将下边的匿名函数转变为普通的屌丝函 ...

  7. P2586 [ZJOI2008]杀蚂蚁(模拟)

    P2586 [ZJOI2008]杀蚂蚁 大模拟. 什么都不想补了. 看变量名感性理解吧 #include<iostream> #include<cstdio> #include ...

  8. js中JSON和JSONP的区别,让你从懵逼到恍然大悟

    说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决?这两个问题目前都有不同的解决方案,比如数据可以用自定义字符串或者用XML来描述,跨域可以通过服 ...

  9. windows 2012 R2 及 centos 7.X 禁用不必要服务

    8.windows 2012 R2 及 centos 7.X 禁用不必要服务 React VR 技术开发群 579149907 1.windows2012 R2 可以禁用以下不必要的服务,以下禁用的服 ...

  10. linux 修改 rsyncd.conf 配置文件

    [root@rsync-server-1 ~]# cat > /etc/rsyncd.conf << EOF #Rsync server #created by sunsky 00: ...