传送门:https://www.luogu.org/problemnew/show/P2622

题面:

题目描述

现有n盏灯,以及m个按钮。每个按钮可以同时控制这n盏灯——按下了第i个按钮,对于所有的灯都有一个效果。按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j]为1,那么当这盏灯开了的时候,把它关上,否则不管;如果为-1的话,如果这盏灯是关的,那么把它打开,否则也不管;如果是0,无论这灯是否开,都不管。

现在这些灯都是开的,给出所有开关对所有灯的控制效果,求问最少要按几下按钮才能全部关掉。

输入输出格式

输入格式:

前两行两个数,n m

接下来m行,每行n个数,a[i][j]表示第i个开关对第j个灯的效果。

输出格式:

一个整数,表示最少按按钮次数。如果没有任何办法使其全部关闭,输出-1

输入输出样例

输入样例#1: 复制

3
2
1 0 1
-1 1 0

输出样例#1: 复制

2

说明

对于20%数据,输出无解可以得分。

对于20%数据,n<=5

对于20%数据,m<=20

上面的数据点可能会重叠。

对于100%数据 n<=10,m<=100

分析:一道状压DP。把灯的开或关的状态用二进制1或0表示,所以开始时灯全部亮的状态就为1<<(n-1)(这里不是1<<n,可以手动模拟一下)这就是当前灯的状态。所以所求答案就是求由初始状态t=1<<(n-1)到t=0的次数。而题中所说的:如果a[i][j]为1,那么当这盏灯开了的时候,把它关上,否则不管 则可以通过按位与判断 ,然后通过按位与操作后进行取反,另一种情况同理。注释见代码

#include<stdio.h>
#include<iostream>
#include<cstring>
#include<bits/stdc++.h>
using namespace std;
int a[200][200];
int ans[1500];
int main()
{
memset(ans, 0x3f, sizeof(ans));//取一个无穷大 操作次数永远不可能达到的次数
int n, m; // n个灯 m个按钮
scanf("%d %d", &n, &m);
for(int i = 1; i <=m; i++)//注意 n和m的位置不要写反
for(int j = 1; j <= n; j++)
scanf("%d", &a[i][j]);
ans[(1 << n ) - 1] = 0;//灯全部打开的情况
for(int t = (( 1 << n) - 1); t >= 0; t--) // 1<<n-1对应n个1的二进制数 t等于0 对应灯全灭
{
for(int i = 1; i <= m; i++)//m次 操作
{
int now = t;
for(int j = 1; j <= n; j++) //进行一次操作后 n个灯的状态都进行改变
{
int temp = 1 << (j-1); //第j个灯 为开的状态
if(a[i][j] == 0)
continue;
else if(a[i][j] == 1 && (t & temp))
now &= ~temp; //x&=~(1<<y) 将某一位数置0
else if(a[i][j] == -1 && !(t & temp))
now |= temp;//x|=(1<<y) 将某一位数置1
}
ans[now] = min(ans[now], ans[t] + 1);
}
}
printf("%d\n", ans[0] == 1061109567 ? -1 : ans[0]);
return 0;
}

洛谷 P2622 关灯问题II【状压DP】的更多相关文章

  1. 洛谷 P2622 关灯问题II(状压DP入门题)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 相关变量解释: int n,m; ];//a[i][j] : 第i个开关对第j个 ...

  2. 关灯问题II 状压DP

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

  3. 洛谷P2622 关灯问题II

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

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

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

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

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

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

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

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

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

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

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

  9. 洛谷P2051 [AHOI2009] 中国象棋(状压dp)

    题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...

随机推荐

  1. 在登陆退出时候使用Vuex

    1.登陆的时候,在登陆模块请求接口,然后获取一个access_token,获取用户权限.保存到缓存里面. 2.退出的时候,请求退出接口,把缓存里面的access_token清除. 一旦要在登陆里面做一 ...

  2. IT日常技能:VMware网络配置

    1.0 基本概念 集线器:把一流量为M的端口分为N个端口,每个端口流量为M/N 交换机:把一流量为M的端口分为N个端口,每个端口流量仍为M 路由器:相当于两块网卡,一块连接外网并负责NAT, 另一块负 ...

  3. P 1025 链表反转

    转跳点:

  4. 每天一点点之vue框架开发 - vue-router路由进阶(路由别名、跳转、默认路由、二级路由、路由守卫)

    路由别名   在main.js中的路由中添加name来创建别名 const routes = [ {path:'/footer',name:footerLink,component:Footer} ] ...

  5. MacOS Safari无响应卡死解决方法

    之前也是用的好好的,突然一次进入一个网页就卡死了,强制退出,后面再重新进入Safari都会处于卡死状态,一直找不到解决方法,Safari也不能卸载重装,想着得等到更新系统或者重装系统,今天看到贴吧一个 ...

  6. 用Spring中的ResponseEntity文件批量压缩下载

    我看了很多网上的demo,先生成ZIP压缩文件,然后再下载. 我这里是生成ZIP文件流 进行下载.(核心代码没多少,就是一些业务代码) @RequestMapping(value = "/& ...

  7. PHP常用的数学函数和字符串函数

    PHP常用函数总结 数学函数 1.abs(): 求绝对值 $abs = abs(-4.2); //4.2 数字绝对值数字 2.ceil(): 进一法取整 echo ceil(9.999); // 10 ...

  8. mysql 时区问题导致的时间相差14小时

    1.mysql 字段名称 类型 begin_time TIME begin_time=08:18:39 2.java数据库连接串 jdbc:mysql://x.x.x.x:3306/y?useUnic ...

  9. PAT 2018 春

    A 1140 Look-and-say Sequence 简单模拟.可能要注意字符串第一个字符和最后一个字符的处理. #include <cstdio> #include <iost ...

  10. js获取浏览器窗口大小

    摘抄:https://blog.csdn.net/qq_27628085/article/details/81947478 常用: JS 获取浏览器窗口大小       // 获取窗口宽度   if ...