总算不再是能用暴力卡常/随机化水过的好T3了。

说是打了两个标签,实际上最关键的是题意转化。

如果你丝毫不转化的话也可以:

 #include<bits/stdc++.h>
using namespace std;
int dp[][],b[],k,n,m,x[],f=,mx;
int main(){
scanf("%d%d%d",&n,&k,&m);
for(int i=;i<=k;++i)scanf("%d",&x[i]);
for(int i=;i<=m;++i)scanf("%d",&b[i]),mx=max(mx,b[i]);
if(mx<=){
memset(dp,0x3f,sizeof dp);dp[][]=;const int maxst=(<<mx-)-;
for(int i=;i<=n;++i){
int base=;if(x[f]==i)f++,base=;memset(dp[i&],0x3f,sizeof dp[]);
for(int j=;j<=m;++j)if(i>=b[j])for(int st=;st<=maxst;++st)
dp[i&][st<<^((<<b[j])-)^base]=min(dp[i&][st<<^((<<b[j])-)^base],dp[i&^][st]+(j?:));
}
printf("%d\n",dp[n&][]);return ;
}
if(!k){puts("");return ;}
int bj=;
for(int i=;i<k;++i)if(x[i]+!=x[i+])bj=;
if(!bj)for(int j=;j<=m;++j)if(b[j]==k){puts("");return ;}
srand(time()+clock());printf("%d\n",+rand()%);
}

考场上56分,直接状压最大的操作区间,再加骗分

(本来想上去讲讲的毕竟勉强算是个单题最高分但其实很水)

然而自然骗分并不稳定。考后再测:

考场上rp生效了!

这个暴力可以稍微讲一讲:

我们先观察数据范围可以发现k超级小但那是全部测试点是正解的事与我无瓜并不会用

其次m也不大但理由同上。

但是那个bi在某些测试点里小,也有些特别大。

和《奇怪的道路》有点莫名其妙的像?状压它!

只不过是把单点的操作换成了区间,其余真的没有什么区别。

时间复杂度O(nm2max(bi))。我不像题解一样只压了4而是尝试压了一下16。T了不要想了。

考场上还剩那么几分钟,干啥?骗分啊!

答案小于4。挺好。只有0123。

0好说啊,所有灯都亮着就是0啊。

1也好说啊,没亮的灯连成一片了而且操作里有能刚好这么长的就是1啊。

2得搜索吧,懒得打。rand一下。

效果不错。

好了好了废话太多说正解。

首先我们的操作是一次一个区间,暴力扫肯定T。区间异或怎么搞?

其实异或运算和加法在很多方面上有互通之处,如果是加法,你会怎么做?

差分啊!然后你就可以惊奇地发现异或的确也可以差分。

那么刚开始对于一个全亮的串,几个不亮的灯就是单点异或。也放进差分数组里处理。

每一个操作就是对于l~r区间异或。其实就是对于相隔距离一定的两个点同时异或一下。

我们的最终目标是得到一个全0串,差分数组全0就表示原区间全0,也就是灯都亮了。

我们继续考虑每一步操作,每次异或两个位置,如果它们都是0你异或完就都是1,和要消除1的目标不符且并不会i作出正贡献。

所以你只会同时选两个1或一个1一个0。前者会使两个1都消失。后者会让两者交换位置。

那么既然你想让它们都消失,就是不断改变1的位置最后让它们两两撞在一起消失掉。

而它每次会移动多少,就是向左右移动它给定的bi位啊。

跑bfs,找出所有1的单源最短路。(不建议打dijkstra或SPFA,常数大,而且就是说明你不理解这个bfs)

因为这个bfs每次走都是一次操作,相当于边权是1,队列里自带单调递增。

不要把边建出来,某牛T了。

然后我们就找出了每一对数字1对撞需要几次操作。

接下来状压它,不断枚举你要让哪两个1对消更新状态即可。

 #include<bits/stdc++.h>
using namespace std;
int n,m,k,b[],x[],y[],cnt,dt[],cost[][],q[],t,dp[];
int main(){y[]=-;
scanf("%d%d%d",&n,&k,&m);
for(int i=;i<=k;++i)scanf("%d",&y[i]);
for(int i=;i<=m;++i)scanf("%d",&b[i]);
for(int i=;i<=k;++i){
if(y[i]+!=y[i+])x[++cnt]=y[i];
if(y[i]-!=y[i-])x[++cnt]=y[i]-;
}
memset(cost,0x3f,sizeof cost);
for(int i=;i<=cnt;++i){
memset(dt,0x3f,sizeof dt);dt[q[t=]=x[i]]=;
for(int h=;h<=t;++h)for(int j=;j<=m;++j){
if(q[h]+b[j]<=n&&dt[q[h]+b[j]]==0x3f3f3f3f)dt[q[++t]=q[h]+b[j]]=dt[q[h]]+;
if(q[h]-b[j]>=&&dt[q[h]-b[j]]==0x3f3f3f3f)dt[q[++t]=q[h]-b[j]]=dt[q[h]]+;
}
for(int j=i+;j<=cnt;++j)cost[i][j]=cost[j][i]=dt[x[j]];
}
memset(dp,0x3f,sizeof dp);dp[]=;
for(int s=;s<<<cnt;++s)for(int i=;i<=cnt;++i)if(!(s&<<i-)){
for(int j=;j<=cnt;++j)if(!(s&<<j-))
dp[s|<<i-|<<j-]=min(dp[s|<<i-|<<j-],dp[s]+cost[i][j]);
break;
}
printf("%d\n",dp[(<<cnt)-]);
}

没上Kb。1008B

星空:差分,状压dp的更多相关文章

  1. 【模拟8.11】星空(差分转化,状压DP,最短路)

    一道很好的题,综合很多知识点. 首先复习差分:      将原来的每个点a[i]转化为b[i]=a[i]^a[i+1],(如果是求和形式就是b[i]=a[i+1]-a[i]) 我们发现这样的方便在于我 ...

  2. Codeforces 79D - Password(状压 dp+差分转化)

    Codeforces 题目传送门 & 洛谷题目传送门 一个远古场的 *2800,在现在看来大概 *2600 左右罢( 不过我写这篇题解的原因大概是因为这题教会了我一个套路罢( 首先注意到每次翻 ...

  3. 【bzoj5161】最长上升子序列 状压dp+打表

    题目描述 现在有一个长度为n的随机排列,求它的最长上升子序列长度的期望. 为了避免精度误差,你只需要输出答案模998244353的余数. 输入 输入只包含一个正整数n.N<=28 输出 输出只包 ...

  4. #12【BZOJ3003】LED BFS+状压DP

    题解: 看到区间修改先想一下差分 这题用差分是为了分析问题 现在的问题就变成了 原序列全为0,要使得特定的k个点变为1,每个操作改变x,y+1 然后我们会发现 对于二元组a,b我们要修改它,实际上是在 ...

  5. HDU 4899 Hero meet devil (状压DP, DP预处理)

    题意:给你一个基因序列s(只有A,T,C,G四个字符,假设长度为n),问长度为m的基因序列s1中与给定的基因序列LCS是0,1......n的有多少个? 思路:最直接的方法是暴力枚举长度为m的串,然后 ...

  6. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  7. nefu1109 游戏争霸赛(状压dp)

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...

  8. poj3311 TSP经典状压dp(Traveling Saleman Problem)

    题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...

  9. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

  10. 【BZOJ2073】[POI2004]PRZ 状压DP

    [BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...

随机推荐

  1. gitblit在windows10上的安装及服务启动报错处理

    折腾一下午算是装好了,心情不错决定分享一下.安装步骤大同小异网上都有,主要是Failed creating java 这个报错,百度出来的没有一个能给我解决的,摸索半天找出一个自己的方式.为报错而来的 ...

  2. ELK 学习笔记之 elasticsearch启动时Warning解决办法

    elasticsearch启动时Warning解决办法: 转载:http://www.dajiangtai.com/community/18136.do?origin=csdn-geek&dt ...

  3. Flume 学习笔记之 Flume NG+Kafka整合

    Flume NG集群+Kafka集群整合: 修改Flume配置文件(flume-kafka-server.conf),让Sink连上Kafka hadoop1: #set Agent name a1. ...

  4. Windows搭建SVN服务器

    安装 1.下载地址:https://www.visualsvn.com/files/VisualSVN-Server-4.0.3-x64.msi 2.开始安装: 3.安装配置: 4.Next直到完成 ...

  5. Kubernetes+Docker+Istio 容器云实践

    随着社会的进步与技术的发展,人们对资源的高效利用有了更为迫切的需求.近年来,互联网.移动互联网的高速发展与成熟,大应用的微服务化也引起了企业的热情关注,而基于Kubernetes+Docker的容器云 ...

  6. bugku web8

    打开网站,是一段PHP代码, <?php extract($_GET); if (!empty($ac)) { $f = trim(file_get_contents($fn)); if ($a ...

  7. Map集合(双列集合)

    Map集合(双列集合)Map集合是键值对集合. 它的元素是由两个值组成的,元素的格式是:key=value. Map集合形式:{key1=value1 , key2=value2 , key3=val ...

  8. vc++源码免杀特殊技巧

    一.Debug 和 Release 编译方式的区别: Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序.Release 称为发布版本,它往往是进行了各种优化,使得程序 ...

  9. [BZOJ3029] 守卫者的挑战

    Description 打开了黑魔法师Vani的大门,队员们在迷宫般的路上漫无目的地搜寻着关押applepi的监狱的所在地.突然,眼前一道亮光闪过.“我,Nizem,是黑魔法圣殿的守卫者.如果你能通过 ...

  10. win10-搭建git工具

    .下载安装 git .生成 SSH 密钥 ssh-keygen -t rsa -C "email@com" -b 4096 .配置gitlab 增加 SSH 密钥. .配置 git ...