• 洛谷3943 星空


    题目描述

    逃不掉的那一天还是来了,小 F 看着夜空发呆。
    天上空荡荡的,没有一颗星星——大概是因为天上吹不散的乌云吧。
    心里吹不散的乌云,就让它在那里吧,反正也没有机会去改变什么了。
    小 C 拿来了一长串星型小灯泡,假装是星星,递给小 F,想让小 F 开心一点。不过,有 着强迫症的小 F 发现,这串一共 n 个灯泡的灯泡串上有 k 个灯泡没有被点亮。小 F 决定 和小 C 一起把这个灯泡串全部点亮。
    不过,也许是因为过于笨拙,小 F 只能将其中连续一段的灯泡状态给翻转——点亮暗灯 泡,熄灭亮灯泡。经过摸索,小 F 发现他一共能够翻转 m 种长度的灯泡段中灯泡的状态。
    小 C 和小 F 最终花了很长很长很长很长很长很长的时间把所有灯泡给全部点亮了。他 们想知道他们是不是蠢了,因此他们找到了你,让你帮忙算算:在最优的情况下,至少需要 几次操作才能把整个灯泡串给点亮?

    solution

    这题第二个转化很巧妙,首先第一个比较简单的转化:转变为差分数组,然后每一次区间翻转就变成了单点翻转,并且我们发现只需要把所有的1变为0就可以达到要求了,但是这里有一个重要的细节,差分数组需要多加一位,因为修改 ([l,r+1]),时可能会改出去,样例就是一个提醒.然后就是第二个转化,每一次我们翻转:如果翻转的两个位置都为1,那么就相当于消除,如果一个0一个1相当于移动,所以一对1可以看做移动了很多步然后消除,所以可以预处理出任意点对消除的步数,bfs处理即可,另外就是注意到1的个数不超过 (16),所以用预处理出来的东西,状压DP,类似于noip愤怒的小鸟了

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    typedef long long ll;
    const int N=40005;
    int n,Q,m,mov[N],st[N],top=0,id[N],DFN=0;bool a[N];
    struct node{
    	int x,y;
    	node(){}
    	node(int _x,int _y){x=_x;y=_y;}
    };
    queue<node>q;
    struct way{
    	int x,w;
    }e[N];
    int tot=0;bool vis[N];
    inline void bfs(int S){
    	int x,u,step;
    	q.push(node(S,0));
    	top=0;vis[S]=1;st[++top]=S;
    	while(!q.empty()){
    		x=q.front().x;step=q.front().y;
    		q.pop();
    		for(RG int i=1;i<=m;i++){
    			for(int k=1;k<=2;k++){
    				if(k==1)u=x+mov[i];
    				else u=x-mov[i];
    				if(u>n || vis[u] || u<1)continue;
    				vis[u]=1;st[++top]=u;
    				if(a[u]==1){
    					e[++tot].x=id[S]|id[u];
    					e[tot].w=step+1;
    					continue;
    				}
    				q.push(node(u,step+1));
    			}
    		}
    	}
    	while(top)vis[st[top]]=0,top--;
    }
    
    int f[1<<16];bool b[N];
    void work()
    {
    	int x;
    	scanf("%d%d%d",&n,&Q,&m);
    	n++;
    	for(int i=1;i<=Q;i++){
    		scanf("%d",&x);
    		b[x]=1;
    	}
    	for(int i=1;i<=n;i++)a[i]=b[i]^b[i-1];
    	for(int i=1;i<=m;i++)scanf("%d",&mov[i]);
    	for(int i=1;i<=n;i++)if(a[i])id[i]=(1<<DFN),DFN++;
    	for(int i=1;i<=n;i++)
    		if(a[i])bfs(i);
    	
    	memset(f,127/3,sizeof(f));
    	f[0]=0;
    	int lim=(1<<DFN)-1;
    	for(RG int j=0;j<=lim;j++){
    		for(RG int i=1;i<=tot;i++){
    			if(j&e[i].x)continue;
    			f[j|e[i].x]=Min(f[j|e[i].x],f[j]+e[i].w);
    		}
    	}
    	printf("%d
    ",f[lim]);
    }
    
    int main()
    {
    	work();
    	return 0;
    }
    
    
  • 相关阅读:
    邀您参加 | BigData & Alluxio 交流会-成都站
    mongodb之使用explain和hint性能分析和优化
    mongodb 3.x 之实用新功能窥看[2] ——使用$lookup做多表关联处理
    mongodb 3.x 之实用新功能窥看[1] ——使用TTLIndex做Cache处理
    asp.net mvc 之旅 —— 第六站 ActionFilter的应用及源码分析
    asp.net mvc 之旅 —— 第五站 从源码中分析asp.net mvc 中的TempData
    分布式架构中一致性解决方案——Zookeeper集群搭建
    搭建高可用的redis集群,避免standalone模式带给你的苦难
    asp.net mvc 之旅—— 第四站 学会用Reflector调试我们的MVC框架代码
    使用强大的可视化工具redislive来监控我们的redis,别让自己死的太惨~~~
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7803907.html
Copyright © 2020-2023  润新知