洛谷 P2622 关灯问题II(状压DP入门题)
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入门题)的更多相关文章
- 关灯问题II 状压DP
关灯问题II 状压DP \(n\)个灯,\(m\)个按钮,每个按钮都会对每个灯有不同影响,问最少多少次使灯熄完. \(n\le 10,m\le 100\) 状压DP的好题,体现了状压的基本套路与二进制 ...
- 洛谷 P2622 关灯问题II【状压DP;隐式图搜索】
题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯--按下了第i个按钮,对于所有的灯都有一个效果.按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j]为1,那么当这盏灯开了的时 ...
- 洛谷 P2622 关灯问题II【状压DP】
传送门:https://www.luogu.org/problemnew/show/P2622 题面: 题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯--按下了第i个按钮,对于所有的 ...
- 洛谷P2622 关灯问题II
洛谷题目链接 声明: 本篇文章不讲基础,对萌新不太友好,(我就是萌新),要学状压$dp$的请另寻,这篇文章只是便于本人查看.... 首先看到$n<=10$,就可以考虑状压了,要求最小值,所以初始 ...
- 【题解】洛谷P3959 [NOIP2017TG] 宝藏(状压DP+DFS)
洛谷P3959:https://www.luogu.org/problemnew/show/P3959 前言 NOIP2017时还很弱(现在也很弱 看出来是DP 但是并不会状压DP 现在看来思路并不复 ...
- 洛谷 P1278 单词游戏 【状压dp】
题目描述 Io和Ao在玩一个单词游戏. 他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致. 游戏可以从任何一个单词开始. 任何单词禁止说两遍,游戏中只 ...
- 洛谷P2704 [NOI2001]炮兵阵地 [状压DP]
题目传送门 炮兵阵地 题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图 ...
- 洛谷P2761 软件补丁问题(状压DP,SPFA)
题意 描述不清... Sol 网络流24题里面怎么会有状压dp?? 真是狗血,不过还是简单吧. 直接用$f[sta]$表示当前状态为$sta$时的最小花费 转移的时候枚举一下哪一个补丁可以搞这个状态 ...
- 洛谷P2831 愤怒的小鸟——贪心?状压DP
题目:https://www.luogu.org/problemnew/show/P2831 一开始想 n^3 贪心来着: 先按 x 排个序,那么第一个不就一定要打了么? 在枚举后面某一个,和它形成一 ...
随机推荐
- 在页面中有overflow-y:auto属性的div,当出现滚动条,点击返回顶部按钮,内容回这个div最顶部
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 初识GetMapping(""),使用方法
GetMapping("value = /SF/{x_num}")与GetMapping("/SF/{x_num}")通过POSTMAN获得的值一样. 注意:G ...
- css的特性
一.继承性: 继承是一种规则,它允许样式不仅应用于某个特定html标签元素,而且应用于其后代. /* 不具有继承性的css样式: */p{border:1px solid red;} 二.特殊性(优先 ...
- NotBacon
What's It Do? The application consists of two components: A Custom Vision Service project that allow ...
- 前后端进行数据交互时候 要优先考虑json格式即简直对形式,[{}] 列表形式 等便于操作的数据结构
前后端进行数据交互时候 要优先考虑json格式即简直对形式,[{}] 列表形式 等便于操作的数据结构
- C语言学习IDE和基本程序结构
任何一门语言的学习,首先要有一个编辑器或集成开发工具IDE, 要不然代码都不知道写到什么地方.对于我这种小白来说,安装个IDE是最好不过的,因为C 语言也是编译语言,写完代码之后,要先编译才能运行,而 ...
- 训练赛-Building Numbers
题意:首先告诉你,一个数字从1开始有两种变换方式:1.当前数字的值加1 2.当前的数字值乘2: 思路:首先把数组里的数字需要的变换次数算出来,然后用前缀和解决: 代码: #include<ios ...
- Sublime Text3 如何开启Debug
打开setting-user 首选项——>Package Settings——>Package Control——>settings-user 添加"debug" ...
- POJ2763-Housewife Wind-树上单点修改区间求和
这道题可以树链剖分做.但是最近在给学弟搞数据结构复习了LCA树状数组RMQ 然后就搞了一发LCA+树状数组维护. dis数组维护当前点到根节点的权值和.则dis(u,v) = dis[u]+dis[v ...
- HDU4349-Xiao Ming's Hope-找规律
打表输出前100之后,找到规律. 不过正确规律是1<<(二进制中1的个数). #include <cstdio> #include <algorithm> usin ...