传送门

https://www.cnblogs.com/violet-acmer/p/9852294.html

题解:

  相关变量解释:

 int n,m;
int a[maxn][];//a[i][j] : 第i个开关对第j个灯的效果。
bool vis[R()];//vis[i] : 判断状态i是否被访问过
struct Node
{
int status;//状态
int minTimes;//来到当前状态按下开关的最小次数
Node(int a=,int b=):status(a),minTimes(b){}
};
queue<Node >myqueue;//用队列中的状态去解锁其他为解锁(访问)过的状态,并能保证被解锁的状态的minTimes最小

  步骤:

  (1):将Node( (1<<n)+1,0 ) 加入队列,因为初始等全是亮的,对应到二进制就是n个1,并且需要 0 次按下开关。

  (2):从队头依次弹出元素,并用当前状态去解锁其他状态,并能保证被其解锁的状态的minTimes是最小的。

  (3):重复(2)过程,直到找到 0 状态或队列为空

AC代码:

 #include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define R(x) (1<<x)
const int maxn=+; int n,m;
int a[maxn][];//a[i][j] : 第i个开关对第j个灯的效果。
bool vis[R()];//vis[i] : 判断状态i是否被访问过
struct Node
{
int status;//状态
int minTimes;//来到当前状态按下开关的最小次数
Node(int a=,int b=):status(a),minTimes(b){}
};
queue<Node >myqueue;//用队列中的状态去解锁其他为解锁(访问)过的状态,并能保证被解锁的状态的minTimes最小 int nextStatus(int nowStatus,int i)
{
int x=nowStatus;
for(int j=;j <= n;++j)//从右往左一一对应
{
if(a[i][j] == && (x>>(j-)&))//一定要注意判断x的第j为是否为1
x ^= (<<(j-));//^ : 相同为0,不同为1
else if(a[i][j] == -)
x |= (<<(j-));
}
return x;
}
int updataQ(Node node)
{
for(int i=;i <= m;++i)
{
int status=nextStatus(node.status,i);//找到当前状态node.status可以解锁的下一状态
if(!vis[status])//如果被访问过,那么其minTimes肯定要小于当前的minTimes+1
myqueue.push(Node(status,node.minTimes+)),vis[status]=true;
if(status == )//判断被解锁的状态是否为0状态
return node.minTimes+;
}
return ;
}
int Solve()
{
mem(vis,false);
while(!myqueue.empty())
myqueue.pop();
myqueue.push(Node(R(n)-,));//步骤(1)
while(!myqueue.empty())//步骤(2)(3)
{
Node node=myqueue.front();
myqueue.pop();
int res=updataQ(node);//更新队列中的状态
if(res != )//判断被解锁的状态是否有0状态,如果有,直接输出,一定是最小的按下次数
return res;
}
return -;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i <= m;++i)
for(int j=n;j >= ;--j)//j : n down 1 用意:与二进制的位数一一对应(从右往左)
scanf("%d",a[i]+j);
printf("%d\n",Solve());
}

洛谷 P2622 关灯问题II(状压DP入门题)的更多相关文章

  1. 关灯问题II 状压DP

    关灯问题II 状压DP \(n\)个灯,\(m\)个按钮,每个按钮都会对每个灯有不同影响,问最少多少次使灯熄完. \(n\le 10,m\le 100\) 状压DP的好题,体现了状压的基本套路与二进制 ...

  2. 洛谷 P2622 关灯问题II【状压DP;隐式图搜索】

    题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯--按下了第i个按钮,对于所有的灯都有一个效果.按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j]为1,那么当这盏灯开了的时 ...

  3. 洛谷 P2622 关灯问题II【状压DP】

    传送门:https://www.luogu.org/problemnew/show/P2622 题面: 题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯--按下了第i个按钮,对于所有的 ...

  4. 洛谷P2622 关灯问题II

    洛谷题目链接 声明: 本篇文章不讲基础,对萌新不太友好,(我就是萌新),要学状压$dp$的请另寻,这篇文章只是便于本人查看.... 首先看到$n<=10$,就可以考虑状压了,要求最小值,所以初始 ...

  5. 【题解】洛谷P3959 [NOIP2017TG] 宝藏(状压DP+DFS)

    洛谷P3959:https://www.luogu.org/problemnew/show/P3959 前言 NOIP2017时还很弱(现在也很弱 看出来是DP 但是并不会状压DP 现在看来思路并不复 ...

  6. 洛谷 P1278 单词游戏 【状压dp】

    题目描述 Io和Ao在玩一个单词游戏. 他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致. 游戏可以从任何一个单词开始. 任何单词禁止说两遍,游戏中只 ...

  7. 洛谷P2704 [NOI2001]炮兵阵地 [状压DP]

    题目传送门 炮兵阵地 题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图 ...

  8. 洛谷P2761 软件补丁问题(状压DP,SPFA)

    题意 描述不清... Sol 网络流24题里面怎么会有状压dp?? 真是狗血,不过还是简单吧. 直接用$f[sta]$表示当前状态为$sta$时的最小花费 转移的时候枚举一下哪一个补丁可以搞这个状态 ...

  9. 洛谷P2831 愤怒的小鸟——贪心?状压DP

    题目:https://www.luogu.org/problemnew/show/P2831 一开始想 n^3 贪心来着: 先按 x 排个序,那么第一个不就一定要打了么? 在枚举后面某一个,和它形成一 ...

随机推荐

  1. MySQL中and和or的优先级的问题

    参考资料: 关于MySQL中AND和OR的优先级的问题 SQL语句中的AND和OR执行顺序问题 MySQL带OR关键字的多条件查询

  2. 老男孩python学习自修第七天【包与模块】

    1.如何导入 from package import module module.function() 常用魔术方法 __init__.py 如果某个文件夹下面有该文件,则该文件夹是一个包,否则只是一 ...

  3. C#使用MemoryStream类读写内存

    MemoryStream和BufferedStream都派生自基类Stream,因此它们有很多共同的属性和方法,但是每一个类都有自己独特的用法.这两个类都是实现对内存进行数据读写的功能,而不是对持久性 ...

  4. over-relaxation

    逐次超松弛sor 参考1https://blog.csdn.net/lusongno1/article/details/68941137 有各种对比和程序 主要就是取了加权平均,没仔细看

  5. Sass(1)--- 了解Sass的发展

    1, Sass 其实是一门编程语言,用来书写css, 它对变量的声明,注释等作出了一系列的规定. 其实Sass写出的文件为SCSS, 它还需要编译成真正的css,供浏览器使用. 2, Sass 的编译 ...

  6. codeforces982F

    The Meeting Place Cannot Be Changed CodeForces - 982F Petr is a detective in Braginsk. Somebody stol ...

  7. vs + babelua + cocos2d-x

    https://blog.csdn.net/dugaoda/article/details/60467037 https://blog.csdn.net/taotanty/article/detail ...

  8. Navicat MySQL 自动备份

    1 新建批处理作业 2 设定(多个库,就轮流选择不同库,然后步骤2) 最后记得保存 3 计划 4 设计批处理作业->设置计划任务 5 输入账号和密码 服务器登录名 服务器密码 6 你可以修改备份 ...

  9. 基准对象object中的基础类型----字典 (六)

    object有如下子类: CLASSES object basestring str unicode buffer bytearray classmethod complex dict enumera ...

  10. 怎么用Verilog描述双向IO口

    在很多情况下,需要使用双向IO.不过最好谨慎使用,在top层使用.网上很多描述的代码甚至是不可以综合并且有语法错误的,还是老实自己写个模块吧. 如果你需要一个口既做输入端口也做输出端口,那么你就需要去 ...